From 2f7a1d52d54e0e8fac9f6fd553a8c9d67970756e Mon Sep 17 00:00:00 2001 From: Andrej Redeky Date: Mon, 17 Jul 2023 12:50:23 +0200 Subject: [PATCH] Huge update with many bugfixes and improvements - Updated Feldarian Base Library (previously directly used UTF and PCMS16 modules were moved to more proper sub-folder) - Added some options also to the library to compile parts conditionally, defaults should not be changed for this project though! - Added ADPCM-XQ as additional dependency (preferred ADPCM encoder/decoder) - Got rid of some dependencies in main project and moved them here - Package is still WIP and is pretty-much single-purpose, it is a slight modified copy of parts from another project as mentioned few times so it looks like it... - Better support for more files (anything libsndfile can open should be importable as PCM S16 WAV at least) - Better xmake project organization - Completely new look and basic application managment, utilizing parts of cpp-gui-template-sdl2 template by @MartinHelmut (also added to third party license list, just in case) - Cleaned-up readme a bit - Cleaned-up license a bit - Removed no longer valid options and added new ones - Removed no longer valid localization and added new ones - Fixed some more multithreading issues (hopefully last from older code...) - Fixed progress not showing correct total sometimes - Added ability to transcode IMA ADPCM (and optionally OGG, default is OFF) files to PCM on export with more conventional sample rate for easier playback (default is ON) - A bit better system for storing and loading original records - When some error is detected, displays error and recreates cache for given archive - System is still far from perfect, it is basically duck-taped on top of existing solution and is inefficient in the way it calculates hashes... it should be better with use of std::spans that is planned... - Allow Blood Money exports in release finally - Autosave settings on change - Some other misc changes --- LICENSE_ThirdParty.md | 625 ++++---- README.md | 4 +- data/localization/English.toml | 19 +- .../localization/\304\214e\305\241tina.toml" | 19 +- data/records/h1 | Bin 26888 -> 0 bytes data/records/h1_1C01A5E5515E2754 | Bin 0 -> 27088 bytes data/records/h1_61B2F1AD80E53F37 | Bin 0 -> 26896 bytes data/records/h2 | Bin 355080 -> 0 bytes data/records/h23_25E9CD9EE932330A | Bin 0 -> 217520 bytes data/records/h23_4A998E2FFDB28762 | Bin 0 -> 217456 bytes data/records/h23_84A8C44058DAB37D | Bin 0 -> 355088 bytes data/records/h23_97CD49005A7260FB | Bin 0 -> 217488 bytes data/records/h23_B8085EC42984367F | Bin 0 -> 355280 bytes data/records/h23_EBB627865BAE612A | Bin 0 -> 217552 bytes data/records/h23_FB5E1F0B1C51E3F0 | Bin 0 -> 217296 bytes data/records/h3 | Bin 217288 -> 0 bytes data/records/h4 | Bin 400744 -> 0 bytes data/records/h4_8A287D30288020AF | Bin 0 -> 462352 bytes data/records/h4_A6C8ED5FFA397C1D | Bin 0 -> 458928 bytes ...piAware.manifest.bak => dpiAware.manifest} | 5 +- src/App/Main.cpp | 31 + src/{ => Config}/Config.h.in | 5 +- src/{ => Config}/Config.hpp | 4 +- src/Core/Application.cpp | 583 +++++++ src/Core/Application.hpp | 43 + src/Core/DPIHandler.hpp | 28 + src/Core/Debug/Instrumentor.hpp | 204 +++ src/Core/Log.cpp | 31 + src/Core/Log.hpp | 63 + src/Core/Resources.hpp | 17 + src/Core/Window.cpp | 62 + src/Core/Window.hpp | 35 + src/{ => G1AT}/ArchiveDialog.cpp | 195 +-- src/{ => G1AT}/ArchiveDialog.hpp | 19 +- src/{ => G1AT}/Hitman1Dialog.cpp | 92 +- src/{ => G1AT}/Hitman1Dialog.hpp | 8 +- src/{ => G1AT}/Hitman23Dialog.cpp | 102 +- src/{ => G1AT}/Hitman23Dialog.hpp | 12 +- src/G1AT/Hitman4Dialog.cpp | 902 +++++++++++ src/G1AT/Hitman4Dialog.hpp | 259 +++ src/G1AT/HitmanDialog.cpp | 563 +++++++ src/G1AT/HitmanDialog.hpp | 63 + src/G1AT/Options.cpp | 209 +++ src/G1AT/Options.hpp | 73 + src/{ => G1AT}/Singleton.hpp | 0 src/{ => G1AT}/Tests.cpp | 2 +- src/{ => G1AT}/Utils.cpp | 81 +- src/G1AT/Utils.hpp | 31 + src/Hitman4Dialog.cpp | 551 ------- src/Hitman4Dialog.hpp | 177 -- src/HitmanDialog.cpp | 614 ------- src/HitmanDialog.hpp | 66 - src/Main.cpp | 303 ---- src/Options.cpp | 168 -- src/Options.hpp | 38 - src/Platform/Linux/DPIHandler.cpp | 43 + src/Platform/Linux/Resources.cpp | 26 + src/Platform/Mac/DPIHandler.cpp | 48 + src/Platform/Mac/Resources.cpp | 25 + src/Platform/Windows/DPIHandler.cpp | 46 + src/Platform/Windows/Resources.cpp | 25 + src/Precompiled.h | 13 +- src/Precompiled.hpp | 169 +- src/Utils.hpp | 70 - src/backends/imgui_impl_opengl3.cpp | 1083 ------------- src/backends/imgui_impl_opengl3.h | 64 - src/backends/imgui_impl_opengl3_loader.h | 844 ---------- src/backends/imgui_impl_sdl2.cpp | 1227 -------------- src/backends/imgui_impl_sdl2.h | 46 - vendor/FeldarianBaseLibrary/.clang-format | 15 + .../EUPL-1.2/EUPL v1_2 BG.txt | 96 ++ .../EUPL-1.2/EUPL v1_2 CS.txt | 103 ++ .../EUPL-1.2/EUPL v1_2 DA.txt | 99 ++ .../EUPL-1.2/EUPL v1_2 DE.txt | 101 ++ .../EUPL-1.2/EUPL v1_2 EL.txt | 91 ++ .../EUPL-1.2/EUPL v1_2 EN.txt | 287 ++++ .../EUPL-1.2/EUPL v1_2 ES.txt | 95 ++ .../EUPL-1.2/EUPL v1_2 ET.txt | 97 ++ .../EUPL-1.2/EUPL v1_2 FI.txt | 95 ++ .../EUPL-1.2/EUPL v1_2 FR.txt | 97 ++ .../EUPL-1.2/EUPL v1_2 HR.txt | 97 ++ .../EUPL-1.2/EUPL v1_2 HU.txt | 97 ++ .../EUPL-1.2/EUPL v1_2 IT.txt | 95 ++ .../EUPL-1.2/EUPL v1_2 LT.txt | 93 ++ .../EUPL-1.2/EUPL v1_2 LV.txt | 97 ++ .../EUPL-1.2/EUPL v1_2 MT.txt | 98 ++ .../EUPL-1.2/EUPL v1_2 NL.txt | 97 ++ .../EUPL-1.2/EUPL v1_2 PL.txt | 98 ++ .../EUPL-1.2/EUPL v1_2 PT.txt | 97 ++ .../EUPL-1.2/EUPL v1_2 RO.txt | 98 ++ .../EUPL-1.2/EUPL v1_2 SK.txt | 98 ++ .../EUPL-1.2/EUPL v1_2 SL.txt | 97 ++ .../EUPL-1.2/EUPL v1_2 SV.txt | 97 ++ vendor/FeldarianBaseLibrary/LICENSE.md | 287 ++++ .../LICENSE_ThirdParty.md | 603 +++++++ vendor/FeldarianBaseLibrary/README.md | 12 + .../include/Feldarian/PCMS16/PCMS16.hpp | 150 ++ .../include/Feldarian}/UTF/Common.hpp | 28 + .../Feldarian}/UTF/GlyphRangesBuilder.hpp | 18 +- .../include/Feldarian}/UTF/Localization.hpp | 84 +- .../include/Feldarian}/UTF/String.hpp | 2 + .../StringViewWrapper-declarations.hpp | 0 .../StringViewWrapper-definitions.hpp | 0 .../StringWrapper-declarations.hpp | 0 .../StringWrapper-definitions.hpp | 0 .../include/Feldarian}/UTF/UTF.hpp | 0 .../src/PCMS16/PCMS16.cpp | 1426 +++++++++++++++++ .../vendor/adpcm-xq/README | 59 + .../vendor/adpcm-xq/adpcm-lib.c | 415 +++++ .../vendor/adpcm-xq/adpcm-lib.h | 44 + .../vendor/adpcm-xq/license.txt | 25 + vendor/FeldarianBaseLibrary/xmake.lua | 162 ++ vendor/imgui-backends/LICENSE.md | 21 + vendor/imgui-backends/README.md | 6 + .../include/imgui/backends/sdl2.h | 38 + .../include/imgui/backends/sdlrenderer2.h | 29 + vendor/imgui-backends/src/sdl2.cpp | 1041 ++++++++++++ vendor/imgui-backends/src/sdlrenderer2.cpp | 265 +++ xmake.lua | 129 +- 119 files changed, 11298 insertions(+), 6016 deletions(-) delete mode 100644 data/records/h1 create mode 100644 data/records/h1_1C01A5E5515E2754 create mode 100644 data/records/h1_61B2F1AD80E53F37 delete mode 100644 data/records/h2 create mode 100644 data/records/h23_25E9CD9EE932330A create mode 100644 data/records/h23_4A998E2FFDB28762 create mode 100644 data/records/h23_84A8C44058DAB37D create mode 100644 data/records/h23_97CD49005A7260FB create mode 100644 data/records/h23_B8085EC42984367F create mode 100644 data/records/h23_EBB627865BAE612A create mode 100644 data/records/h23_FB5E1F0B1C51E3F0 delete mode 100644 data/records/h3 delete mode 100644 data/records/h4 create mode 100644 data/records/h4_8A287D30288020AF create mode 100644 data/records/h4_A6C8ED5FFA397C1D rename manifests/{dpiAware.manifest.bak => dpiAware.manifest} (50%) create mode 100644 src/App/Main.cpp rename src/{ => Config}/Config.h.in (86%) rename src/{ => Config}/Config.hpp (88%) create mode 100644 src/Core/Application.cpp create mode 100644 src/Core/Application.hpp create mode 100644 src/Core/DPIHandler.hpp create mode 100644 src/Core/Debug/Instrumentor.hpp create mode 100644 src/Core/Log.cpp create mode 100644 src/Core/Log.hpp create mode 100644 src/Core/Resources.hpp create mode 100644 src/Core/Window.cpp create mode 100644 src/Core/Window.hpp rename src/{ => G1AT}/ArchiveDialog.cpp (70%) rename src/{ => G1AT}/ArchiveDialog.hpp (87%) rename src/{ => G1AT}/Hitman1Dialog.cpp (55%) rename src/{ => G1AT}/Hitman1Dialog.hpp (72%) rename src/{ => G1AT}/Hitman23Dialog.cpp (76%) rename src/{ => G1AT}/Hitman23Dialog.hpp (86%) create mode 100644 src/G1AT/Hitman4Dialog.cpp create mode 100644 src/G1AT/Hitman4Dialog.hpp create mode 100644 src/G1AT/HitmanDialog.cpp create mode 100644 src/G1AT/HitmanDialog.hpp create mode 100644 src/G1AT/Options.cpp create mode 100644 src/G1AT/Options.hpp rename src/{ => G1AT}/Singleton.hpp (100%) rename src/{ => G1AT}/Tests.cpp (96%) rename src/{ => G1AT}/Utils.cpp (76%) create mode 100644 src/G1AT/Utils.hpp delete mode 100644 src/Hitman4Dialog.cpp delete mode 100644 src/Hitman4Dialog.hpp delete mode 100644 src/HitmanDialog.cpp delete mode 100644 src/HitmanDialog.hpp delete mode 100644 src/Main.cpp delete mode 100644 src/Options.cpp delete mode 100644 src/Options.hpp create mode 100644 src/Platform/Linux/DPIHandler.cpp create mode 100644 src/Platform/Linux/Resources.cpp create mode 100644 src/Platform/Mac/DPIHandler.cpp create mode 100644 src/Platform/Mac/Resources.cpp create mode 100644 src/Platform/Windows/DPIHandler.cpp create mode 100644 src/Platform/Windows/Resources.cpp delete mode 100644 src/Utils.hpp delete mode 100644 src/backends/imgui_impl_opengl3.cpp delete mode 100644 src/backends/imgui_impl_opengl3.h delete mode 100644 src/backends/imgui_impl_opengl3_loader.h delete mode 100644 src/backends/imgui_impl_sdl2.cpp delete mode 100644 src/backends/imgui_impl_sdl2.h create mode 100644 vendor/FeldarianBaseLibrary/.clang-format create mode 100644 vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 BG.txt create mode 100644 vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 CS.txt create mode 100644 vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 DA.txt create mode 100644 vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 DE.txt create mode 100644 vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 EL.txt create mode 100644 vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 EN.txt create mode 100644 vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 ES.txt create mode 100644 vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 ET.txt create mode 100644 vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 FI.txt create mode 100644 vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 FR.txt create mode 100644 vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 HR.txt create mode 100644 vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 HU.txt create mode 100644 vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 IT.txt create mode 100644 vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 LT.txt create mode 100644 vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 LV.txt create mode 100644 vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 MT.txt create mode 100644 vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 NL.txt create mode 100644 vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 PL.txt create mode 100644 vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 PT.txt create mode 100644 vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 RO.txt create mode 100644 vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 SK.txt create mode 100644 vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 SL.txt create mode 100644 vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 SV.txt create mode 100644 vendor/FeldarianBaseLibrary/LICENSE.md create mode 100644 vendor/FeldarianBaseLibrary/LICENSE_ThirdParty.md create mode 100644 vendor/FeldarianBaseLibrary/README.md create mode 100644 vendor/FeldarianBaseLibrary/include/Feldarian/PCMS16/PCMS16.hpp rename {src => vendor/FeldarianBaseLibrary/include/Feldarian}/UTF/Common.hpp (66%) rename {src => vendor/FeldarianBaseLibrary/include/Feldarian}/UTF/GlyphRangesBuilder.hpp (91%) rename {src => vendor/FeldarianBaseLibrary/include/Feldarian}/UTF/Localization.hpp (79%) rename {src => vendor/FeldarianBaseLibrary/include/Feldarian}/UTF/String.hpp (99%) rename {src => vendor/FeldarianBaseLibrary/include/Feldarian}/UTF/Strings-impl/StringViewWrapper-declarations.hpp (100%) rename {src => vendor/FeldarianBaseLibrary/include/Feldarian}/UTF/Strings-impl/StringViewWrapper-definitions.hpp (100%) rename {src => vendor/FeldarianBaseLibrary/include/Feldarian}/UTF/Strings-impl/StringWrapper-declarations.hpp (100%) rename {src => vendor/FeldarianBaseLibrary/include/Feldarian}/UTF/Strings-impl/StringWrapper-definitions.hpp (100%) rename {src => vendor/FeldarianBaseLibrary/include/Feldarian}/UTF/UTF.hpp (100%) create mode 100644 vendor/FeldarianBaseLibrary/src/PCMS16/PCMS16.cpp create mode 100644 vendor/FeldarianBaseLibrary/vendor/adpcm-xq/README create mode 100644 vendor/FeldarianBaseLibrary/vendor/adpcm-xq/adpcm-lib.c create mode 100644 vendor/FeldarianBaseLibrary/vendor/adpcm-xq/adpcm-lib.h create mode 100644 vendor/FeldarianBaseLibrary/vendor/adpcm-xq/license.txt create mode 100644 vendor/FeldarianBaseLibrary/xmake.lua create mode 100644 vendor/imgui-backends/LICENSE.md create mode 100644 vendor/imgui-backends/README.md create mode 100644 vendor/imgui-backends/include/imgui/backends/sdl2.h create mode 100644 vendor/imgui-backends/include/imgui/backends/sdlrenderer2.h create mode 100644 vendor/imgui-backends/src/sdl2.cpp create mode 100644 vendor/imgui-backends/src/sdlrenderer2.cpp diff --git a/LICENSE_ThirdParty.md b/LICENSE_ThirdParty.md index 3551888..8a33cd7 100644 --- a/LICENSE_ThirdParty.md +++ b/LICENSE_ThirdParty.md @@ -1,205 +1,103 @@ -# scnlib - 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 +# adpcm-xq + Copyright (c) David Bryant + All rights reserved. - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and +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 Conifer Software 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. + +# cpp-gui-template-sdl2 - (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 +MIT License - (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. +Copyright (c) 2022-2023 Martin Helmut Fieber - 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. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: - 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. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. - 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. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. - 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. +# imgui +The MIT License (MIT) - 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. +Copyright (c) 2014-2023 Omar Cornut - 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. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: - END OF TERMS AND CONDITIONS +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. - APPENDIX: How to apply the Apache License to your work. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. +# libsamplerate +Copyright (c) 2012-2016, Erik de Castro Lopo +All rights reserved. - Copyright [yyyy] [name of copyright owner] +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. - http://www.apache.org/licenses/LICENSE-2.0 +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. - 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. +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 +HOLDER 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. # libsdl Copyright (C) 1997-2023 Sam Lantinga @@ -724,108 +622,12 @@ necessary. Here is a sample; alter the names: That's all there is to it! -# libsamplerate -Copyright (c) 2012-2016, Erik de Castro Lopo -All rights reserved. +# NotoSans +Copyright 2022 The Noto Project Authors (https://github.com/notofonts) -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 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 -HOLDER 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. - -# imgui -The MIT License (MIT) - -Copyright (c) 2014-2023 Omar Cornut - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -# xxhash -xxHash Library -Copyright (c) 2012-2021 Yann Collet -All rights reserved. - -BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) - -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, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. - -# toml++ -MIT License - -Copyright (c) Mark Gillard - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -# NotoSans -Copyright 2022 The Noto Project Authors (https://github.com/notofonts) - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -https://scripts.sil.org/OFL +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://scripts.sil.org/OFL ----------------------------------------------------------- @@ -914,3 +716,252 @@ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. + +# scnlib + 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 + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + +# toml++ +MIT License + +Copyright (c) Mark Gillard + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +# xxhash +xxHash Library +Copyright (c) 2012-2021 Yann Collet +All rights reserved. + +BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) + +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, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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/README.md b/README.md index 9a8a502..7153052 100644 --- a/README.md +++ b/README.md @@ -38,8 +38,8 @@ Format | Open | Save | Export | Import * Ability to show modified entries in archives thanks to original records caching. * Automatically ignore unchanged original files from original archives when trying to import. * Records caching feature can be disabled, same as the option which ignores unchanged files on import. Beware that disabling records caching also causes unchanged files to get imported. - * Currently pre-packaged with __Steam__ data and default __English__ language. - * When you have different version, just remove `data/records` folder and let it regenerate records on first archive reload. + * Cache gets initialized for the first time on archive open. + * It can be reset for each tool under options when needed. * Currently 2 supported languages - __English__ and __Czech__ * New localizations can be added by copying `data/localization/English.toml`, translating the entries and placing the copied file back into `data/localization` * For example, you could create `Deutsch.toml` which would contain translations to __German__ language and place it in the mentioned folder. diff --git a/data/localization/English.toml b/data/localization/English.toml index 4c04222..9819faa 100644 --- a/data/localization/English.toml +++ b/data/localization/English.toml @@ -12,14 +12,19 @@ ARCHIVE_DIALOG_SAVE = "Save" ARCHIVE_DIALOG_SAVE_INTO = "Save into" ARCHIVE_DIALOG_EXPORT_TO = "Export into" ARCHIVE_DIALOG_IMPORT_FROM = "Import from" +ARCHIVE_DIALOG_CLOSE = "Close" +ARCHIVE_DIALOG_RELOAD = "Reload" +ARCHIVE_DIALOG_EXIT = "Exit" +ARCHIVE_DIALOG_PROCESSING = "Processing..." ARCHIVE_DIALOG_PROGRESS_SUMMARY = "Currently processing item {} from {}..." ARCHIVE_DIALOG_NO_ARCHIVE = "There is currently no opened archive." -ARCHIVE_DIALOG_LOADED_ARCHIVE = "Opened archive:\n{}" +ARCHIVE_DIALOG_FILE_MENU = "File" SDL2_INITIALIZATION_ERROR = "Couldn't initialize SDL2!\n\"{}\"" MESSAGEBOX_ERROR_GENERIC_TITLE = "Error" MESSAGEBOX_WARNING_GENERIC_TITLE = "Warning" HITMAN_DIALOG_LOADING_ORIGINAL_RECORDS = "Loading the original records..." HITMAN_DIALOG_ERROR_UNKNOWN_FORMAT_IN_ARCHIVE = "Found an unknown format inside the archive!" +HITMAN_DIALOG_ERROR_CORRUPTED_ORIGINAL_RECORDS_CACHE = "Original records cache corrupted for current archive! Trying to rebuild..." HITMAN_DIALOG_WARNING_IMPORT_LOADING_DATA = "Couldn't load the input data, skipping the import!" HITMAN_DIALOG_WARNING_IMPORT_DECODING_DATA = "Couldn't decode the input data, skipping the import!" HITMAN_DIALOG_WARNING_IMPORT_CREATING_NATIVE_DATA = "Couldn't create the native data, skipping the import!" @@ -30,11 +35,21 @@ HITMAN_1_DIALOG_ERROR_MISSING_BIN = "Couldn't find the necessary *.bin file!" HITMAN_23_DIALOG_ERROR_MISSING_SCENES = "Couldn't find the necessary Scenes directory!" SETTINGS_DIALOG_TITLE = "Settings" SETTINGS_DIALOG_COMMON_GROUP = "Common" +SETTINGS_DIALOG_HITMAN_RESET_RECORDS_CACHE = "Reset original records cache" +SETTINGS_DIALOG_HITMAN1_GROUP = "Codename 47 Specific" +SETTINGS_DIALOG_HITMAN23_GROUP = "Silent Assassin / Contracts Specific" +SETTINGS_DIALOG_HITMAN4_GROUP = "Blood Money Specific" +SETTINGS_DIALOG_HITMAN4_EXPORT_WITH_LIP_DATA = "Export LIP data block with sound data when available" SETTINGS_DIALOG_DISABLE_WARNINGS = "Disable warnings" -SETTINGS_DIALOG_CHECK_DATA_ORIGINALITY = "Check the originality of the data in archive" SETTINGS_DIALOG_IMPORT_ORIGINAL_FILES = "Import the unchanged original files" SETTINGS_DIALOG_DIRECT_IMPORT = "Import the files directly without conversions (turning this OFF is experimental!)" SETTINGS_DIALOG_FIX_CHANNELS = "Fix the number of channels on import (turning this OFF is experimental!)" SETTINGS_DIALOG_FIX_SAMPLE_RATE = "Fix the sample rate on import (turning this OFF is experimental!)" SETTINGS_DIALOG_TRANSCODE_TO_ORIGINAL_FORMAT = "Transcode to the exact format of original game data on import" +SETTINGS_DIALOG_TRANSCODE_TO_PLAYABLE_FORMAT = "Transcode to easily playable PCM format on export" +SETTINGS_DIALOG_TRANSCODE_OGG_TO_PCM = "Transcode OGG files also to PCM format on export" SETTINGS_DIALOG_LANGUAGE = "Language" +FILE_DIALOG_FILTER_ALL_SUPPORTED = "All Supported" +FILE_DIALOG_FILTER_HITMAN1_SPEECH = "Codename 47 Speech" +FILE_DIALOG_FILTER_HITMAN23_STREAMS = "Silent Assassin / Contracts Streams" +FILE_DIALOG_FILTER_HITMAN4_STREAMS = "Blood Money Streams" diff --git "a/data/localization/\304\214e\305\241tina.toml" "b/data/localization/\304\214e\305\241tina.toml" index db83a87..c53b497 100644 --- "a/data/localization/\304\214e\305\241tina.toml" +++ "b/data/localization/\304\214e\305\241tina.toml" @@ -12,14 +12,19 @@ ARCHIVE_DIALOG_SAVE = "Uložit" ARCHIVE_DIALOG_SAVE_INTO = "Uložit do" ARCHIVE_DIALOG_EXPORT_TO = "Rozbalit do" ARCHIVE_DIALOG_IMPORT_FROM = "Vložit z" +ARCHIVE_DIALOG_CLOSE = "Zavřít" +ARCHIVE_DIALOG_RELOAD = "Znovu načíst" +ARCHIVE_DIALOG_EXIT = "Ukončit" +ARCHIVE_DIALOG_PROCESSING = "Processing..." ARCHIVE_DIALOG_PROGRESS_SUMMARY = "Spracovávám položku {} z {}..." ARCHIVE_DIALOG_NO_ARCHIVE = "Momentálne není otevřen žáden archiv." -ARCHIVE_DIALOG_LOADED_ARCHIVE = "Momentálne otevřen archiv:\n{}" +ARCHIVE_DIALOG_FILE_MENU = "Soubor" SDL2_INITIALIZATION_ERROR = "Nepodařilo se inicializovat SDL2! Chyba: \"{}\"" MESSAGEBOX_ERROR_GENERIC_TITLE = "Chyba" MESSAGEBOX_WARNING_GENERIC_TITLE = "Varování" HITMAN_DIALOG_LOADING_ORIGINAL_RECORDS = "Načítávám originální data..." HITMAN_DIALOG_ERROR_UNKNOWN_FORMAT_IN_ARCHIVE = "Neznámej formát souboru v archivu!" +HITMAN_DIALOG_ERROR_CORRUPTED_ORIGINAL_RECORDS_CACHE = "Cache s originálními daty archivu je poškozená! Pokouším se data znovu vytvořit..." HITMAN_DIALOG_WARNING_IMPORT_LOADING_DATA = "Nepodařilo se načíst data, přeskakuji import!" HITMAN_DIALOG_WARNING_IMPORT_DECODING_DATA = "Nepodařilo se dekódovat data, přeskakuji import!" HITMAN_DIALOG_WARNING_IMPORT_CREATING_NATIVE_DATA = "Nepodařilo se vytvořit nativní data, přeskakuji import!" @@ -30,11 +35,21 @@ HITMAN_1_DIALOG_ERROR_MISSING_BIN = "Nebyl nalezen nezbitný *.bin soubor s daty HITMAN_23_DIALOG_ERROR_MISSING_SCENES = "Nebyla nalezena nezbitná zložka Scenes!" SETTINGS_DIALOG_TITLE = "Nastavení" SETTINGS_DIALOG_COMMON_GROUP = "Pro všechny" +SETTINGS_DIALOG_HITMAN_RESET_RECORDS_CACHE = "Smazat cache originálních záznamú" +SETTINGS_DIALOG_HITMAN1_GROUP = "Specifické pro Codename 47" +SETTINGS_DIALOG_HITMAN23_GROUP = "Specifické pro Silent Assassin / Contracts" +SETTINGS_DIALOG_HITMAN4_GROUP = "Specifické pro Blood Money" +SETTINGS_DIALOG_HITMAN4_EXPORT_WITH_LIP_DATA = "Exportovat se zvukovými daty také datový blok LIP (pokud je přítomný)" SETTINGS_DIALOG_DISABLE_WARNINGS = "Vypnout upozornění" -SETTINGS_DIALOG_CHECK_DATA_ORIGINALITY = "Skontrolovat originalitu dat v archivu" SETTINGS_DIALOG_IMPORT_ORIGINAL_FILES = "Importovat i nezměnené originální soubory" SETTINGS_DIALOG_DIRECT_IMPORT = "Importovat soubory napřímo bez konverzií (vypnuti tohodle nastavení je experimentální!)" SETTINGS_DIALOG_FIX_CHANNELS = "Opravit počet kanálů při importu (vypnuti tohodle nastavení je experimentální!)" SETTINGS_DIALOG_FIX_SAMPLE_RATE = "Opravit vzorkovací frekvenci při importu (vypnuti tohodle nastavení je experimentální!)" SETTINGS_DIALOG_TRANSCODE_TO_ORIGINAL_FORMAT = "Převést při importu na originální formát" +SETTINGS_DIALOG_TRANSCODE_TO_PLAYABLE_FORMAT = "Převést při exportu na lehce přehratelný PCM formát" +SETTINGS_DIALOG_TRANSCODE_OGG_TO_PCM = "Převést při exportu také OGG soubory na PCM formát" SETTINGS_DIALOG_LANGUAGE = "Jazyk" +FILE_DIALOG_FILTER_ALL_SUPPORTED = "Všechny podporované" +FILE_DIALOG_FILTER_HITMAN1_SPEECH = "Codename 47 Speech" +FILE_DIALOG_FILTER_HITMAN23_STREAMS = "Silent Assassin / Contracts Streams" +FILE_DIALOG_FILTER_HITMAN4_STREAMS = "Blood Money Streams" diff --git a/data/records/h1 b/data/records/h1 deleted file mode 100644 index 9f8eb13d8603eca7f127f8fa129d597d71b96739..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26888 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

Da`ULFGT-zbxwiLKLTY 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 U#fZHpE&$eNel)-S*ZJ}P0Cxx16#xJL diff --git a/data/records/h1_1C01A5E5515E2754 b/data/records/h1_1C01A5E5515E2754 new file mode 100644 index 0000000000000000000000000000000000000000..b4a4af3e1300500ab5eac14222618beb688ec619 GIT binary patch literal 27088 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

nrBQ$Q2qgE_v@Kl%N-zsQ1f4+@q6hd2C< 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 M7DmU{|2jYZKYI?OF8}}l literal 0 HcmV?d00001 diff --git a/data/records/h2 b/data/records/h2 deleted file mode 100644 index b946d948faa39e59535f4aba83b35cc732975954..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 355080 zcmeEvc{G;Y7q*au%+Wxk$P_}9gd`z}k|ZjU6h#P`qNEf;Qb{T#MTSyIDosLoDal(Y zBn@OJsU&^d_x1gA-{FIN64=v9W*QU}JmWlRHIe-6K0=UBCtD_|?j0hXp=I#3B>`=cD7T zZ5Q4Iju+XyQVMWxI_?s-YhnHBPsVL`0oSDC-w)dr^vl&s=}ZTlpN_x2oIDsY_Va%E zB*5kAc=P9-suN#rdD)f-xEvjiu{~wK$F?dfF$FDu{)kY>HJRY%3IV`}!`Q&M{TQEN zUto~t#@{*b8e1QbBLO(#_o;YEhmSh&;KRisc~1KGlP=|J80zS!$ivvOanW(EvF#&n zuM(?t7DeOf2H%~8-R5s8S_-%rU0!naWy_r9ZrelF0zQt8A5fEj-u2;mayX{_7!I$_ z)BOSG62^c$;`hnj>j-V%VsEGgbC3FcnM(7=R8N$$P#%TGPY2)8H~X5nZv#f2n|*bM zepUMR(2;0)HjStcrp;ap5_!?Mz1}mW7O5(O8Vr84c0+vGQ+Z!ySX-$6cYBF$<+-J) zVu1Pm>Ne&HS@H|ZGcoe>r=@oAI|s`OlFIJ`$jKr)JDV zz@ZK5{=Cgopw!PXo@+5?ece1<=+Qg6=WGDx`&L$Y-@K#Wq=sn0Vz#8W-^8KoQoLNc zGF}V5kJx_)@4x5Y;Vg6QzBb?p{UG;7i?6G;J&i{njhCzH?6KThy(M-L;E46RGl;FT z@LT$Z8E$~X9;5#LMm^ED{tJ8r3M`=iHgr7p%;C}+-ju${L;XYae_UJpo=?YT=Ez{$ zpUUs;`Oz>@gb&6B)xYN-yG6cg)C!6&037xZwSO8C$7`D!{#p9j3-Aeaob&k&k;+FO zCh%*Z`?siQLdz73D@zK^(d}OzQK0-gRTK`uk zue$!^+uM!DOJM$BjHu&R7L**Jmt~;VYK5L(*QsJpD%_vw*DQwqBi7I5NZxwUQwOKG z7yu4?jM~1?eoN<_GKz}F!vIH|fA$(*j~1(}+a!q5pI`Kg_N$u3?^46GZxo>`_`G-B z&KAu2ep=R9)x{G$%10Hxk2pUwFmrNtDw zY)a|_dFUhc_t!)md&yo_U0{Yezlyj*$`8+pU9BYz@(BH-E0A+`7r%O3_aroaFhj;% zESo#f7o*?ho|Ll>c9gE0j5+_r?k6iq1xi?{V9uv)>zbqrPQN!x#mJwKNC@01d?9KO z)&@$y?kH?NBic6nUA+(*uM5;xPn!}xVlhVl=Z-W=bh|jXp#dYG_TEh1F1kn*cYc2o zkKO2SVuDu@7p!k1`urT+zU@fdX^Zu{C`-L;gl_TxC!L8J7fFss#um)G(XwQUO z@mB#?qql$Q__NPhGbU;AYycdgU->_H6ka!K`R)RH6Q#d~Del(UE%MRZ4)gt^XUE-H zG^TSOH%33^j_;2uR;U;kVGZpg_OE-*+8Oo%o776@1CG$In)1B*CGL0I`iAxoLcbsD zFCQ?wJgc=D^Zmu0uDfQ3^fnGUgFHh2$x4Nu{db^m)tGsJBlJh>cD5@G+XUwZ)$= z&Ce8@3pk>GGxMaI_4NJs*umOD;iD6D`|ezr^{HPIaK!lK4#wpRsK@Jt!*4_3(ZjxL zsD{UR8Nk{^=?9ClHxaTL|6E{)xkc?i73~V;%bs(u@?+$4P5fOCgs}${W9&yoj@G1< zLcvAynEe^=q+|V3>f=+nDd_$QP5$b@Ge-LiIX5FO<&~E|P@rBhJq| zia{y!Y9n$?VC|#qf6ob{bsZLJSgpjY4|f&g@~OqUI(K9Azq_eiUxR$iD|Jl&pKKN| z_7yEUUUAc(~{<${zRLbs^x0^P$M`t^wz@Ck~tZ0GFo! z{=qq-YXwBgLoQ zPqbw55|255{n{t!We1*q?t;0WC_fo5W}Oz} zZ4b67%03Xjy1?!1u+B+snDgz;wp9VQIyls_<vWjInPF-!3r;-feBxkJ(>yROdMFmpd%D8f9)VV{cp+Q6ODo0ysi{h9ip$tgKpKFb-2)3+QEMWsUV*RZ;r&xNW z_Uh^!FTfH0FB>(L=qB;C2|Aebqx(h4%GVKRq69JW`?=#wuJP!7tZ{<&L5ETM_v$!r zQ`&+r?j@M}8}ET)m$4G}G9Ir%%kQ?Zoiu!s)*k6lxSzu}sO?WN{&3>ii5X6-i$ET9 z02L1jPS5O5mUFDZ?0@^wO?H~!1mp5x?oj%}a``apl?&oF%jv@RVUJVW|1w9%A^))9 z)v|7o*Q4WWT}?F`=RU~~nF#V`bX-krt)$C`UAARAKpu1?wf&Zvr9tyAab`GW0FJny zKC2ruEMGKdlesS7g7oz@Gw`61l|)QK(KW!;>FxWyH|9?Z>?;b|4>;&>>i&yxEZFxX z%IhotkbV@Q<7ubfOInWB>!>G@-R zsPglA_8Re;EEC=+f#It*ZsSsamgcH@H)sN#+Q%dl!My$^&Kgf0av4c ze{S4C@r+fjHZt{q!y2T{zw7+ZiqVp)8`QD^NAzD|?4gWJPPg)JuLc~k{~YuLJL4*+ ztD0fPr`V`){_@8nOVSNMUYP!U(X9TZPoq?d24HN5^f&eQ&yqcHE7EI9ed`bXPsQ(* z@iw$QRG3~cbiYLCKUo0||5r_wMX8{>hVEBX`I(6)@&`t})HTNFKbi1Nj$X4*)|&4H z`N{PDr<+)5xgSy3)qugHM|Y|}kJP@N?hEpW^;Nn@#i>3l_o7@N;L`N=XT2z^Qx}f3 zmWR1P-7oZe-`b9EOv=;pN6TMZlsEU(nda8xK7hmbslPu~`KYbzUiEGnJHX)#rQ&Bx z__uR620ktt1^NZfDC+ttHwfrG^4M?U?ii3qj8AG{`q*m`0w-NPKz=1%{&iX9+Jz7J zHIIWV%6@dUKfktX(Z6wO^8rV!pTd{>t!|b`Zpen;hC2VBX-mcwC-qHhn1hyoR)1c7 zS@`k|1_o&Si`*0QfXx23Cd~OF&t5Ux;JD20^mQPQ&<|YOZp?dWmEPZy1vp}V?e5>H zBc&;yFZN@8sN;JlIJs=D_lb3U9_aQZn|k_=$c`N!>J2zzeGQhhDJA=|&uDW59I<}` zHzzJ;536n;2WKA&cTE`o*7TFdQBKVGjYv4OVh-OrsWX`0KhkI^zYE)`&VVLpUxz;b z(LSG_DKy@l-E9CkVt$vJ94i!j**@J9gJ0q~=OZ_3@QUq_enrS9%(9f7qj9S<1+0?yU5yL+IL)TyUSzVOO7#~AdeV-uV>Nzp(W2_ z7DoY&*dGtxo*vdE@Nlm>X8$@gOg-H#9s(SG1GW7ay>-!#t~9x=#OU9>0xJSf%+NS**9Ycdes6moSTk6=_C`9!K8Rmh-tAL*!asZw$cxe2m(@Gqa6d0Cpne75VB=B8M`@x; z-E@u1k8Cjezxu_=y$^)~vd@4lYJYxit!WRFJ(zJ3vwu&nm^EfN=gX6NcIfZ>-~D3b zz~QVn0DBkZ|8Oid+$SDkey&a*aK!oa@MJ;X;aiH&W845o?2l_X3AV%8UiV#_gO-1E0)qzUgeb*8&?+4?#>%Wx7A6!y_8Q;x)A&(}T zNd^U_K>LXE&E@%fWgm+x%Of!M9mnTF?J9X5@hHsilU*c~ACyqunSeRJjBT4n9v;eim^0|tO2*5`|@oBusk+wyk632?;kpP4qzfc@sC-u^bgp^wz@QJgxV%<{ti zBW18RQ1+iBSBgXruWwU|1>lJOXW0fHtuzxE!v%XAr5_l@=YE>Lz$d(AjKiP~$Roz@ zm+6xOKYA z-nwdB{EzGY!Zp4@51leF{^xtnJQ|*}e1}^=-%#gwTl&*E|D@OQ)k_18=)cY2%Ml)v zjyXOB+Yp7vcR0DrSU%~AQUM(C`wn%>I9yQ79^H+*e@u$ZU1-B*@eH%SOvf&qYnCFT zSHB+GN7xT%ubeBr&>}nR_0aeuzVCCwb3adRZwotSeMvpmRsC9dK{p)p`-E)O1pPKVVarsW4 zX!3qse1fg9@x=vmuYcNO3GxX2IrCe}w*{-lMw;ye9L^Bx_#NzSTj?ui$R!a3xHKJC zjOuvvZ}v_uFEhXq`mgYIL+!cos;N1NfWsQ1wy(Y=`G$SD)@0jdfFt_1D`3*R;qB*_ zmtyXhYH{0|ZUrn6Y{iU!!A{Bed*&I-^I&bF&L^(LZ#_=Lf1MbEdH>!grY9Nq?VIyB z%=znGEVIzo+*{KYbHC)?_}=k}>#2pQ82viuAlt~(v1RVK_=$>ZDvmSOXr`-X@V#w%IxGr`~iJX{sN9ydf<;A}>%?`_&mmEg3oQ?^rL_y_^G6R!O!c{{OR=zR=(gIePGw&dRKRte*`~|)%6X= zb#(Ul4$ciYJ{P`^;J+oEFs`|`M=swb8gSq!QTbWYYjekOb-A; z%Ryd~F3)UyJgKih>MM}?3Z%XQsjmR~m5Z)lNqq%UUxAhN6;w0s>CO4HOpy=6A13kp zzjypTsgFSFBar$Cq&@weW%dW>`7smwl^mxzXzlEecpTCBJBr9?5n`!hY|E^{KAHdCDC6e7|qG#y4VQg$6^zYY=s;PS~@o-iiH{g(C zi0XgwDfj80zfAj1W)&n*>7(PllS|chsb;APCPQ+TGjyEU`UH&X4_utLK46ZtfT}d) zPDAB?nm8lLi?>zM-QX(VYV`gws!uQ_b-Y-|)7GzVhw@v&8m7(sPeD*GZ&nCv{64n733ku z5ET!*Q)lXD81SlPA>fcdiHd)!-!2?t`h8Ak7`lJcMwuv`EIynQbsTW8(W&x`>IbCB za7ymW`KTp`$g-;52RfZG-jyQi9)n{1RrRe_d^kRorO#V?u{0rgRO?@}==UweCfbS#p1F4U| zTz!O?!xv-Px%pN+eE{RDMc@CVe!_PrVYm5PiZJ%^pI$$KQGEnv`4Qiq{8M-+*k<)p zjDBG?f5JO>ok&c6PKq)nzc#b=0lr_%TgSj)MD% zGaYACUqI4hpz(4;c{~rMK9yyUMN@CCvJsCMv=3uU{eG;=BF8%?H;JcU@;jzfJ>k1l zJ=e)~GV~vjKgj&{pR7{ZSs{20)W zi1!o1k0JaR!jB>R7#u(5Pv=(@DYpQZ3tCABzL4yqT9v64GkFiwD)H6|K<4e*6nOpj7|-YwycNoL-^MdM+uG{ zJICwX{~Dj|61Hn${pwG~ZFix41b^iFVY`BUxmqb5O#QFLAAX)6dvK2E+CMqJ@axOT zgArpt@0U-4@j>v%nm_MUo%m|Y%eF+o<>>1_#`cu`9^0y{#1ynVtK)x|jn82efAg#3 zWB&H|2v)~0F#A6LtKYv_{r;;{!e{KYL|DX&6ZS8Jcv0hf_)MRx4nJo8jU8emhT+3j(Ss2T0A%45MoA^4{ozelo#s}cLLuW3U9k)y=ksv zOpw|}z=7XLl`p;;P_D|cx1jh({WL00-e>>r_gPlIk1~2cV^qJJQGMrMT|byneON~I zSxJ3F*49U4b^XG3V!!tO$B6%BCt6Ufy+W``4SbWR`1>xF7~Q_c;p~zpuZQB75$`wm?%gnY5bNr}jj6x;OpiN4 zq-E(yod4r!?S}ZWr}Dna82#JrCAyX8mZpjU#{Wg~2Wjzj)wZYc=)?R#jcDrp8H8Mm z5PI0?mw>5{UaqRM$8u}+me@rgFGiQ&8N}9E_$__I3^%|L`Cl027uxD4e{Gpf?2Q3m zkVmX9X3qzki65LaYWy8iA@&UwUoSp7!oJ#5RISJnaH!Et9UtPK|G9nkr{^z{^4^@G zro6(adpFEKBL0z4ej~?M*A_KI-cTR>!Ed6jpMNHwlzs32*?GcBXdiSG6=ybo(9^Qc zsxF@3Q9c;{NM>Bunn&kTuc(ZL?}HD7`h88Cz-eLS2ZSUr{6$i~m(=ei^?OPEUQ)jo z^d};I^S@rdca7dl{k-kj;mQeb%lz9(X_ob3QV9{}i%o z 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 diff --git a/data/records/h23_25E9CD9EE932330A b/data/records/h23_25E9CD9EE932330A new file mode 100644 index 0000000000000000000000000000000000000000..69a044aa4baf0665a281e5d14c29c5f536f2bfee GIT binary patch literal 217520 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 literal 0 HcmV?d00001 diff --git a/data/records/h23_4A998E2FFDB28762 b/data/records/h23_4A998E2FFDB28762 new file mode 100644 index 0000000000000000000000000000000000000000..0341f896c0505380f527554a24a2437e579747f9 GIT binary patch literal 217456 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 {A&ApS4Ip3w{U*tE~b|9ZC804Ml^156`D@8p{ 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 U!o4!Tvd>Xk>pYP>h{or?05BDh^8f$< literal 0 HcmV?d00001 diff --git a/data/records/h23_97CD49005A7260FB b/data/records/h23_97CD49005A7260FB new file mode 100644 index 0000000000000000000000000000000000000000..43739d1a42e36551a0f08beab9d0c1853de2e4ff GIT binary patch literal 217488 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à*+#qSMC4zp;J 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 We#EMJc>M8T%Qmy;Fuwdz{r>^+flki= literal 0 HcmV?d00001 diff --git a/data/records/h23_B8085EC42984367F b/data/records/h23_B8085EC42984367F new file mode 100644 index 0000000000000000000000000000000000000000..9ed1c9958b858d724124df1db44f6a4c349c9adb GIT binary patch literal 355280 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%0A+) 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 qsheYGOD;qI2T^|F{CmFCnz*0R z1n-wWwwQkWmY*?3=n{-iHp9+2OP;`dIfh*}A(J{lpopW}5Qc`PHu zb#wMTkY9-M`>$Rw4z!4Hv!tHh@PFz$^LVP8E`VQ4mO{2{WlchgB721-BwN|8a8t=% zAw(`og_5OskYvjik;<+Rl7uHxRJP<%DN+iN_q_j_nZLiEbLPyrnK&xBS71CLIIG(j^qd7A^jT^hyJodwa$!9soN0!JLh`LzgXYBNvl1|_aiqk+y#l7|PaVC8R1B7R0&pL^H&eo;qP?+004kG+W^V9QB z9sbj#{)P?Qrj3aGCl=4;ig-(9<;U|9ih8AN zN4X8;88a>^Ao8sZxoSsiCeta$J)r(vi?mq8mAn0?q!kTX zMu6*~eDT(MyJ`jlT074$)4vs{eT$V$<1T))o6_J1gpH9#h<#fI7-
F~VK%?lb;P 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 literal 0 HcmV?d00001 diff --git a/data/records/h3 b/data/records/h3 deleted file mode 100644 index 30be8159e619eb0641684f5763c0493509bbc03a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 217288 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 RvHu$Is~fg~fBB&L{|~gWZ`=R? diff --git a/data/records/h4 b/data/records/h4 deleted file mode 100644 index 7523bcffe764cfa2b79ffd7e94210a1ad24e8ce8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 400744 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 diff --git a/data/records/h4_8A287D30288020AF b/data/records/h4_8A287D30288020AF new file mode 100644 index 0000000000000000000000000000000000000000..f2d68dbe06541926f0da8b08928dab8493079804 GIT binary patch literal 462352 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 literal 0 HcmV?d00001 diff --git a/data/records/h4_A6C8ED5FFA397C1D b/data/records/h4_A6C8ED5FFA397C1D new file mode 100644 index 0000000000000000000000000000000000000000..8889ab54cdfa4853f0173f00409ad1e1018a79a6 GIT binary patch literal 458928 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࿄{Ro#nO*PMesuuv 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 literal 0 HcmV?d00001 diff --git a/manifests/dpiAware.manifest.bak b/manifests/dpiAware.manifest similarity index 50% rename from manifests/dpiAware.manifest.bak rename to manifests/dpiAware.manifest index 0ea4b22..bfc1a27 100644 --- a/manifests/dpiAware.manifest.bak +++ b/manifests/dpiAware.manifest @@ -1,8 +1,9 @@ - - PerMonitorV2, unaware + + true/pm + permonitorv2,permonitor,system diff --git a/src/App/Main.cpp b/src/App/Main.cpp new file mode 100644 index 0000000..8ec6a2d --- /dev/null +++ b/src/App/Main.cpp @@ -0,0 +1,31 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 +// + +#include + +#include +#include +#include + +#include + +int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { + try { + APP_PROFILE_BEGIN_SESSION_WITH_FILE("App", "profile.json"); + + { + APP_PROFILE_SCOPE("Test scope"); + App::Application app{G1AT_TITLE}; + app.run(); + } + + APP_PROFILE_END_SESSION(); + } catch (std::exception& e) { + APP_ERROR("Main process terminated with: {}", e.what()); + } + + return 0; +} diff --git a/src/Config.h.in b/src/Config/Config.h.in similarity index 86% rename from src/Config.h.in rename to src/Config/Config.h.in index d42f8ea..151600d 100644 --- a/src/Config.h.in +++ b/src/Config/Config.h.in @@ -13,6 +13,9 @@ #define G1AT_VERSION_STRING_GIT "${GIT_TAG_LONG}" +#define G1AT_COMPANY_NAMESPACE "${G1AT_COMPANY_NAMESPACE}" +#define G1AT_COMPANY_NAME "${G1AT_COMPANY_NAME}" + #define G1AT_NAME "${G1AT_NAME}" #define G1AT_DESCRIPTION "${G1AT_DESCRIPTION}" #define G1AT_HOMEPAGE "${G1AT_HOMEPAGE}" @@ -28,7 +31,7 @@ #define NDEBUG 1 #endif -#ifdef G1AT_DEBUG_BUILD +#if G1AT_DEBUG_BUILD #define G1AT_TITLE G1AT_NAME " (" G1AT_VERSION_STRING_GIT ")" #else #define G1AT_TITLE G1AT_NAME " (" G1AT_VERSION_STRING ")" diff --git a/src/Config.hpp b/src/Config/Config.hpp similarity index 88% rename from src/Config.hpp rename to src/Config/Config.hpp index 4283228..6fcd4ec 100644 --- a/src/Config.hpp +++ b/src/Config/Config.hpp @@ -8,6 +8,8 @@ extern "C" { + // Generated by xmake from "src/Config.h.in" -#include +#include + } diff --git a/src/Core/Application.cpp b/src/Core/Application.cpp new file mode 100644 index 0000000..9fc3c6d --- /dev/null +++ b/src/Core/Application.cpp @@ -0,0 +1,583 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 +// + +#include + +#include "Application.hpp" + +#include "Debug/Instrumentor.hpp" +#include "DPIHandler.hpp" +#include "Resources.hpp" + +#include + +#include +#include +#include +#include + +namespace +{ + +std::shared_ptr s_SelectedDialog; +OrderedSet> s_Dialogs; +String8CI s_OpenFilters; + +} + +bool BuildFontAtlas() +{ + if (!g_GlyphRangesBuilder.NeedsBuild()) + return true; + + auto fontsPath = GetProgramPath().path(); + fontsPath /= L"data"; + fontsPath /= L"fonts"; + if (!exists(fontsPath)) + return false; + + ImFontGlyphRangesBuilder builder; + + const auto glyphRanges = g_GlyphRangesBuilder.Build(); + for (const auto& glyphRange : glyphRanges) + { + const uint32_t translatedGlyphRange[3]{glyphRange.first, glyphRange.second, 0}; + builder.AddRanges(translatedGlyphRange); + } + + static ImVector imguiRanges; + imguiRanges.clear(); + + builder.BuildRanges(&imguiRanges); + + ImFontConfig config; + config.SizePixels = 18; + config.OversampleH = 3; + config.OversampleV = 1; + config.MergeMode = false; + + const ImGuiIO &io = ImGui::GetIO(); + io.Fonts->Clear(); + + const auto fonts = GetAllFilesInDirectory(String8CI(fontsPath), "", false); + for (const auto& font : fonts) + { + const auto fontExtension = font.path().extension(); + if (fontExtension != StringViewWCI(L".ttf") && fontExtension != StringViewWCI(L".otf")) + continue; + + io.Fonts->AddFontFromFileTTF(font.c_str(), config.SizePixels, &config, imguiRanges.Data); + config.MergeMode = true; + } + + if (!config.MergeMode) + io.Fonts->AddFontDefault(&config); + + ImGui_ImplSDLRenderer2_DestroyFontsTexture(); + ImGui_ImplSDLRenderer2_CreateFontsTexture(); + + return true; +} + +void ReloadOriginalData() +{ + for (auto& hitmanDialog : s_Dialogs) + hitmanDialog->ReloadOriginalData(); +} + +void InitializeOpenFilters() +{ + if (!s_OpenFilters.empty()) + return; + + auto hitmanFilters = Hitman1Dialog::GetOpenFilter(); + std::ranges::copy(Hitman23Dialog::GetOpenFilter(), std::back_inserter(hitmanFilters)); + std::ranges::copy(Hitman4Dialog::GetOpenFilter(), std::back_inserter(hitmanFilters)); + + s_OpenFilters = MakeFileDialogFilter(hitmanFilters); +} + +namespace App { + +Application::Application(const std::string& title) { + APP_PROFILE_FUNCTION(); + + auto dataPath = GetProgramPath().path(); + if (dataPath.empty()) + { + m_exit_status = ExitStatus::FAILURE; + return; + } + + dataPath /= L"data"; + if (!exists(dataPath)) + { + m_exit_status = ExitStatus::FAILURE; + return; + } + + const auto localizationPath = dataPath / L"localization"; + if (!exists(localizationPath)) + { + m_exit_status = ExitStatus::FAILURE; + return; + } + + const auto fontsPath = dataPath / L"fonts"; + if (!exists(fontsPath)) + { + m_exit_status = ExitStatus::FAILURE; + return; + } + + const auto localizationFilePaths = GetAllFilesInDirectory(String8CI(localizationPath), ".toml", false); + if (localizationFilePaths.empty()) + { + m_exit_status = ExitStatus::FAILURE; + return; + } + + bool foundEnglish = false; + for (const auto& localizationFilePath : localizationFilePaths) + { + if (!g_LocalizationManager.LoadLocalization(localizationFilePath)) + { + m_exit_status = ExitStatus::FAILURE; + return; + } + + if (localizationFilePath.path().stem() == StringViewWCI(L"English")) + foundEnglish = true; + } + if (!foundEnglish) + { + m_exit_status = ExitStatus::FAILURE; + return; + } + + if (!g_LocalizationManager.SetDefaultLanguage("English")) + { + m_exit_status = ExitStatus::FAILURE; + return; + } + + Options::Get().Load(); + Options::Get().Save(); + + const unsigned int init_flags{SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER}; + if (SDL_Init(init_flags) != 0) { + APP_ERROR("Error: %s\n", SDL_GetError()); + m_exit_status = ExitStatus::FAILURE; + return; + } + + SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1"); + + m_window = std::make_unique(Window::Settings{title}); + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io{ImGui::GetIO()}; + + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard | ImGuiConfigFlags_DockingEnable | + ImGuiConfigFlags_ViewportsEnable; + + const std::string user_config_path{SDL_GetPrefPath(G1AT_COMPANY_NAMESPACE, G1AT_NAME)}; + APP_DEBUG("User config path: {}", user_config_path); + + //// Absolute imgui.ini path to preserve settings independent of app location. + //static const std::string imgui_ini_filename{user_config_path + "imgui.ini"}; + //io.IniFilename = imgui_ini_filename.c_str(); + io.IniFilename = nullptr; + io.LogFilename = nullptr; + + //// ImGUI font + //const float font_scaling_factor{DPIHandler::get_scale()}; + //const float font_size{18.0F * font_scaling_factor}; + //const std::string font_path{Resources::font_path("Manrope.ttf").generic_string()}; + // + //io.Fonts->AddFontFromFileTTF(font_path.c_str(), font_size); + //io.FontDefault = io.Fonts->AddFontFromFileTTF(font_path.c_str(), font_size); + DPIHandler::set_global_font_scaling(&io); + + // Setup Platform/Renderer backends + ImGui_ImplSDL2_InitForSDLRenderer(m_window->get_native_window(), m_window->get_native_renderer()); + ImGui_ImplSDLRenderer2_Init(m_window->get_native_renderer()); +} + +Application::~Application() { + APP_PROFILE_FUNCTION(); + + ImGui_ImplSDLRenderer2_Shutdown(); + ImGui_ImplSDL2_Shutdown(); + ImGui::DestroyContext(); + + m_window.reset(); + + SDL_Quit(); + + Options::Get().Save(); +} + +ExitStatus App::Application::run() { + APP_PROFILE_FUNCTION(); + + if (m_exit_status == ExitStatus::FAILURE) { + return m_exit_status; + } + + m_running = true; + while (m_running) + { + APP_PROFILE_SCOPE("MainLoop"); + + SDL_Event event{}; + while (SDL_PollEvent(&event) == 1) { + APP_PROFILE_SCOPE("EventPolling"); + + ImGui_ImplSDL2_ProcessEvent(&event); + + if (event.type == SDL_QUIT) { + stop(); + } + + if (event.type == SDL_WINDOWEVENT && + event.window.windowID == SDL_GetWindowID(m_window->get_native_window())) { + on_event(event.window); + } + } + + if (!m_running) + { + for (auto& hitmanDialog : s_Dialogs) + { + m_running |= hitmanDialog->IsInProgress(); + if (m_running) + break; + } + } + + if (!m_running) + { + for (auto& hitmanDialog : s_Dialogs) + { + switch (hitmanDialog->UnsavedChangesPopup()) + { + case 1: { + hitmanDialog->Save(hitmanDialog->GetPath(), false); + break; + } + case 0: { + break; + } + default: + case -1: { + m_running = true; + break; + } + } + + if (m_running) + break; + } + } + + if (!m_running) + break; + + BuildFontAtlas(); + + // Start the Dear ImGui frame + ImGui_ImplSDL2_NewFrame(); + ImGui_ImplSDLRenderer2_NewFrame(); + ImGui::NewFrame(); + + if (!m_minimized) + { + const auto dockID = ImGui::DockSpaceOverViewport(); + + const bool isSelectedDialog = s_SelectedDialog != nullptr; + const bool inProgress = s_SelectedDialog && s_SelectedDialog->IsInProgress(); + const bool isSavingAllowed = s_SelectedDialog && s_SelectedDialog->IsSaveAllowed(); + const bool isExportAllowed = s_SelectedDialog && s_SelectedDialog->IsExportAllowed(); + const bool isImportAllowed = s_SelectedDialog && s_SelectedDialog->IsImportAllowed(); + + if (ImGui::BeginMainMenuBar()) + { + if (ImGui::BeginMenu(g_LocalizationManager.Localize("ARCHIVE_DIALOG_FILE_MENU").c_str())) + { + if (ImGui::MenuItem(g_LocalizationManager.Localize("ARCHIVE_DIALOG_OPEN").c_str())) + { + InitializeOpenFilters(); + + auto [archivePath, archiveType] = OpenFileDialog(s_OpenFilters); + + auto alreadyOpened = false; + for (const auto& dialog : s_Dialogs) + { + if (dialog->GetPath() == archivePath.path()) + { + alreadyOpened = true; + break; + } + } + + // TODO - some error messages/warnings wouldn't hurt... + if (!alreadyOpened && !archivePath.empty() && archiveType != 0) + { + switch (archiveType) + { + case 1: + { + + const auto* originalSelectedDialog = s_SelectedDialog.get(); + + for (const auto& filter : Hitman1Dialog::GetOpenFilter() | std::views::values) + { + if (archivePath.path().extension() != StringViewWCI(filter.path().extension())) + continue; + + s_SelectedDialog = *s_Dialogs.insert(std::make_shared()).first; + s_SelectedDialog->Load(archivePath); + break; + } + + if (s_SelectedDialog.get() != originalSelectedDialog) + break; + + for (const auto& filter : Hitman23Dialog::GetOpenFilter() | std::views::values) + { + if (archivePath.path().extension() != StringViewWCI(filter.path().extension())) + continue; + + s_SelectedDialog = *s_Dialogs.insert(std::make_shared()).first; + s_SelectedDialog->Load(archivePath); + break; + } + + if (s_SelectedDialog.get() != originalSelectedDialog) + break; + + for (const auto& filter : Hitman4Dialog::GetOpenFilter() | std::views::values) + { + if (archivePath.path().extension() != StringViewWCI(filter.path().extension())) + continue; + + s_SelectedDialog = *s_Dialogs.insert(std::make_shared()).first; + s_SelectedDialog->Load(archivePath); + break; + } + + break; + } + case 2: + { + s_SelectedDialog = *s_Dialogs.insert(std::make_unique()).first; + s_SelectedDialog->Load(archivePath); + break; + } + case 3: + { + s_SelectedDialog = *s_Dialogs.insert(std::make_unique()).first; + s_SelectedDialog->Load(archivePath); + break; + } + case 4: + { + s_SelectedDialog = *s_Dialogs.insert(std::make_unique()).first; + s_SelectedDialog->Load(archivePath); + break; + } + } + } + } + + if (!isSelectedDialog || inProgress) + ImGui::BeginDisabled(); + + if (ImGui::MenuItem(g_LocalizationManager.Localize("ARCHIVE_DIALOG_CLOSE").c_str())) + { + s_Dialogs.erase(s_SelectedDialog); + s_SelectedDialog.reset(); + } + + if (!isSelectedDialog || inProgress) + ImGui::EndDisabled(); + + ImGui::Separator(); + + if (!isSelectedDialog || inProgress) + ImGui::BeginDisabled(); + + if (ImGui::MenuItem(g_LocalizationManager.Localize("ARCHIVE_DIALOG_RELOAD").c_str())) + { + assert(s_SelectedDialog); + s_SelectedDialog->Load(s_SelectedDialog->GetPath()); + } + + if (!isSelectedDialog || inProgress) + ImGui::EndDisabled(); + + if (!isSelectedDialog || inProgress || !isSavingAllowed) + ImGui::BeginDisabled(); + + if (ImGui::MenuItem(g_LocalizationManager.Localize("ARCHIVE_DIALOG_SAVE").c_str())) + { + assert(s_SelectedDialog); + s_SelectedDialog->Save(s_SelectedDialog->GetPath(), true); + } + + if (ImGui::MenuItem(g_LocalizationManager.Localize("ARCHIVE_DIALOG_SAVE_INTO").c_str())) + { + assert(s_SelectedDialog); + + const auto [archivePath, archiveType] = SaveFileDialog(MakeFileDialogFilter(s_SelectedDialog->GetSaveFilter())); + + s_SelectedDialog->Save(archivePath, true); + } + + if (!isSelectedDialog || inProgress || !isSavingAllowed) + ImGui::EndDisabled(); + + ImGui::Separator(); + + if (!isSelectedDialog || inProgress || !isExportAllowed) + ImGui::BeginDisabled(); + + if (ImGui::MenuItem(g_LocalizationManager.Localize("ARCHIVE_DIALOG_EXPORT_TO").c_str())) + { + assert(s_SelectedDialog); + s_SelectedDialog->Export(BrowseDirectoryDialog()); + } + + if (!isSelectedDialog || inProgress || !isExportAllowed) + ImGui::EndDisabled(); + + if (!isSelectedDialog || inProgress || !isImportAllowed) + ImGui::BeginDisabled(); + + if (ImGui::MenuItem(g_LocalizationManager.Localize("ARCHIVE_DIALOG_IMPORT_FROM").c_str())) + { + assert(s_SelectedDialog); + s_SelectedDialog->Import(BrowseDirectoryDialog()); + } + + if (!isSelectedDialog || inProgress || !isImportAllowed) + ImGui::EndDisabled(); + + ImGui::Separator(); + + ImGui::MenuItem(g_LocalizationManager.Localize("SETTINGS_DIALOG_TITLE").c_str(), nullptr, &Options::Get().opened); + + ImGui::Separator(); + + if (ImGui::MenuItem(g_LocalizationManager.Localize("ARCHIVE_DIALOG_EXIT").c_str())) + stop(); + + ImGui::EndMenu(); + } + + ImGui::EndMainMenuBar(); + } + + for (auto hitmanDialogIt = s_Dialogs.begin(); hitmanDialogIt != s_Dialogs.end(); ++hitmanDialogIt) + { + auto& hitmanDialog = *hitmanDialogIt; + ImGui::SetNextWindowDockID(dockID, ImGuiCond_Once); + switch (hitmanDialog->DrawDialog()) + { + case -1: { + if (s_SelectedDialog == hitmanDialog) + s_SelectedDialog.reset(); + + hitmanDialogIt = s_Dialogs.erase(hitmanDialogIt); + break; + } + case 0: { + break; + } + case 1: { + s_SelectedDialog = hitmanDialog; + break; + } + } + if (hitmanDialogIt == s_Dialogs.end()) + break; + } + + Options::Get().DrawDialog(); + } + + // Rendering + ImGui::Render(); + + SDL_SetRenderDrawColor(m_window->get_native_renderer(), 100, 100, 100, 255); + SDL_RenderClear(m_window->get_native_renderer()); + ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData()); + SDL_RenderPresent(m_window->get_native_renderer()); + } + + return m_exit_status; +} + +void App::Application::stop() +{ + for (auto& hitmanDialog : s_Dialogs) + { + if (hitmanDialog->IsInProgress()) + return; + } + + m_running = false; + + for (auto& hitmanDialog : s_Dialogs) + { + switch (hitmanDialog->UnsavedChangesPopup()) + { + case 1: { + hitmanDialog->Save(hitmanDialog->GetPath(), false); + break; + } + case 0: { + break; + } + default: + case -1: { + m_running = true; + break; + } + } + + if (m_running) + break; + } +} + +void Application::on_event(const SDL_WindowEvent& event) { + switch (event.event) { + case SDL_WINDOWEVENT_CLOSE: + return on_close(); + case SDL_WINDOWEVENT_MINIMIZED: + return on_minimize(); + case SDL_WINDOWEVENT_RESTORED: + return on_shown(); + } +} + +void Application::on_minimize() { + m_minimized = true; +} + +void Application::on_shown() { + m_minimized = false; +} + +void Application::on_close() { + stop(); +} + +} // namespace App diff --git a/src/Core/Application.hpp b/src/Core/Application.hpp new file mode 100644 index 0000000..038471d --- /dev/null +++ b/src/Core/Application.hpp @@ -0,0 +1,43 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 +// + +#pragma once + +#include "Window.hpp" + +namespace App { + +enum class ExitStatus : int { SUCCESS = 0, FAILURE = 1 }; + +class Application { + public: + explicit Application(const std::string& title); + ~Application(); + + Application(const Application&) = delete; + Application(Application&&) = delete; + Application& operator=(Application other) = delete; + Application& operator=(Application&& other) = delete; + + ExitStatus run(); + void stop(); + + void on_event(const SDL_WindowEvent& event); + void on_minimize(); + void on_shown(); + void on_close(); + + private: + ExitStatus m_exit_status{ExitStatus::SUCCESS}; + std::unique_ptr m_window{nullptr}; + + bool m_running{true}; + bool m_minimized{false}; + bool m_show_some_panel{true}; + bool m_show_debug_panel{false}; +}; + +} // namespace App diff --git a/src/Core/DPIHandler.hpp b/src/Core/DPIHandler.hpp new file mode 100644 index 0000000..159a90c --- /dev/null +++ b/src/Core/DPIHandler.hpp @@ -0,0 +1,28 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 +// + +#pragma once + +#include "Window.hpp" + +namespace App { + +struct WindowSize { + int width; + int height; +}; + +class DPIHandler { + public: + [[nodiscard]] static float get_scale(); + + [[nodiscard]] static WindowSize get_dpi_aware_window_size(const Window::Settings& settings); + + static void set_render_scale(SDL_Renderer* renderer); + static void set_global_font_scaling(ImGuiIO* io); +}; + +} // namespace App diff --git a/src/Core/Debug/Instrumentor.hpp b/src/Core/Debug/Instrumentor.hpp new file mode 100644 index 0000000..5c31c41 --- /dev/null +++ b/src/Core/Debug/Instrumentor.hpp @@ -0,0 +1,204 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 +// + +#pragma once + +#include + +namespace App::Debug { + +using FloatingPointMicroseconds = std::chrono::duration; + +struct ProfileResult { + std::string name; + FloatingPointMicroseconds start; + std::chrono::microseconds elapsed_time; + std::thread::id thread_id; +}; + +struct InstrumentationSession { + const std::string name; + explicit InstrumentationSession(std::string session_name) : name(std::move(session_name)) {} +}; + +class Instrumentor { + public: + Instrumentor(const Instrumentor&) = delete; + Instrumentor(Instrumentor&&) = delete; + Instrumentor& operator=(Instrumentor other) = delete; + Instrumentor& operator=(Instrumentor&& other) = delete; + + void begin_session(const std::string& name, const std::string& filepath = "results.json") { + const std::lock_guard lock(m_mutex); + + if (m_current_session != nullptr) { + // If there is already a current session, then close it before beginning new one. + // Subsequent profiling output meant for the original session will end up in the + // newly opened session instead. That's better than having badly formatted + // profiling output. + APP_ERROR("Instrumentor::begin_session('{0}') when session '{1}' already open.", + name, + m_current_session->name); + internal_end_session(); + } + m_output_stream.open(filepath); + + if (m_output_stream.is_open()) { + m_current_session = std::make_unique(name); + write_header(); + } else { + APP_ERROR("Instrumentor could not open results file '{0}'.", filepath); + } + } + + void end_session() { + const std::lock_guard lock(m_mutex); + internal_end_session(); + } + + void write_profile(const ProfileResult& result) { + std::stringstream json; + + std::string name{result.name}; + std::replace(name.begin(), name.end(), '"', '\''); + + json << std::setprecision(3) << std::fixed; + json << ",{"; + json << R"("cat":"function",)"; + json << "\"dur\":" << (result.elapsed_time.count()) << ','; + json << R"("name":")" << name << "\","; + json << R"("ph":"X",)"; + json << "\"pid\":0,"; + json << R"("tid":")" << result.thread_id << "\","; + json << "\"ts\":" << result.start.count(); + json << "}"; + + const std::lock_guard lock(m_mutex); + if (m_current_session != nullptr) { + m_output_stream << json.str(); + m_output_stream.flush(); + } + } + + static Instrumentor& get() { + static Instrumentor instance; + return instance; + } + + private: + Instrumentor() : m_current_session(nullptr) {} + + ~Instrumentor() { + end_session(); + } + + void write_header() { + m_output_stream << R"({"otherData": {},"traceEvents":[{})"; + m_output_stream.flush(); + } + + void write_footer() { + m_output_stream << "]}"; + m_output_stream.flush(); + } + + // Note: you must already own lock on m_Mutex before + // calling InternalEndSession() + void internal_end_session() { + if (m_current_session != nullptr) { + write_footer(); + m_output_stream.close(); + } + } + + std::mutex m_mutex; + std::unique_ptr m_current_session; + std::ofstream m_output_stream; +}; + +class InstrumentationTimer { + public: + explicit InstrumentationTimer(std::string name) + : m_name(std::move(name)), + m_start_time_point(std::chrono::steady_clock::now()) {} + + InstrumentationTimer(const InstrumentationTimer&) = delete; + InstrumentationTimer(InstrumentationTimer&&) = delete; + InstrumentationTimer& operator=(InstrumentationTimer other) = delete; + InstrumentationTimer& operator=(InstrumentationTimer&& other) = delete; + + ~InstrumentationTimer() { + if (!m_stopped) { + stop(); + } + } + + void stop() { + const auto end_time_point{std::chrono::steady_clock::now()}; + const auto high_res_start{FloatingPointMicroseconds{m_start_time_point.time_since_epoch()}}; + const auto elapsed_time{ + std::chrono::time_point_cast(end_time_point).time_since_epoch() - + std::chrono::time_point_cast(m_start_time_point) + .time_since_epoch()}; + + Instrumentor::get().write_profile( + {m_name, high_res_start, elapsed_time, std::this_thread::get_id()}); + + m_stopped = true; + } + + private: + const std::string m_name; + bool m_stopped{false}; + const std::chrono::time_point m_start_time_point; +}; + +} // namespace App::Debug + +#if G1AT_ENABLE_PROFILING +// Resolve which function signature macro will be used. Note that this only +// is resolved when the (pre)compiler starts, so the syntax highlighting +// could mark the wrong one in your editor! +#if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || \ + (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__) +// There is an implicit decay of an array into a pointer. +// NOLINTNEXTLINE +#define APP_FUNC_SIG __PRETTY_FUNCTION__ +#elif defined(__DMC__) && (__DMC__ >= 0x810) +#define APP_FUNC_SIG __PRETTY_FUNCTION__ +#elif defined(__FUNCSIG__) +#define APP_FUNC_SIG __FUNCSIG__ +#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || \ + (defined(__IBMCPP__) && (__IBMCPP__ >= 500)) +#define APP_FUNC_SIG __FUNCTION__ +#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550) +#define APP_FUNC_SIG __FUNC__ +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) +#define APP_FUNC_SIG __func__ +#elif defined(__cplusplus) && (__cplusplus >= 201103) +#define APP_FUNC_SIG __func__ +#else +#define APP_FUNC_SIG "APP_FUNC_SIG unknown!" +#endif + +#define JOIN_AGAIN(x, y) x##y +#define JOIN(x, y) JOIN_AGAIN(x, y) +#define APP_PROFILE_BEGIN_SESSION(name) ::App::Debug::Instrumentor::get().begin_session(name) +#define APP_PROFILE_BEGIN_SESSION_WITH_FILE(name, file_path) \ + ::App::Debug::Instrumentor::get().begin_session(name, file_path) +#define APP_PROFILE_END_SESSION() ::App::Debug::Instrumentor::get().end_session() +#define APP_PROFILE_SCOPE(name) \ + const ::App::Debug::InstrumentationTimer JOIN(timer, __LINE__) { \ + name \ + } +#define APP_PROFILE_FUNCTION() APP_PROFILE_SCOPE(APP_FUNC_SIG) +#else +#define APP_PROFILE_BEGIN_SESSION(name) +#define APP_PROFILE_BEGIN_SESSION_WITH_FILE(name, file_path) +#define APP_PROFILE_END_SESSION() +#define APP_PROFILE_SCOPE(name) +#define APP_PROFILE_FUNCTION() +#endif diff --git a/src/Core/Log.cpp b/src/Core/Log.cpp new file mode 100644 index 0000000..aa9366d --- /dev/null +++ b/src/Core/Log.cpp @@ -0,0 +1,31 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 +// + +#include + +#include "Log.hpp" + +namespace App { + +Log::Log() { + std::vector log_sinks; + + const spdlog::level::level_enum level{spdlog::level::debug}; + + log_sinks.emplace_back(std::make_shared()); + log_sinks.emplace_back(std::make_shared("app.log", true)); + + log_sinks[0]->set_pattern("%^[%T] %n(%l): %v%$"); + log_sinks[1]->set_pattern("[%T] [%l] %n(%l): %v"); + + m_logger = std::make_shared("APP", begin(log_sinks), end(log_sinks)); + spdlog::register_logger(m_logger); + spdlog::set_default_logger(m_logger); + m_logger->set_level(level); + m_logger->flush_on(level); +} + +} // namespace App diff --git a/src/Core/Log.hpp b/src/Core/Log.hpp new file mode 100644 index 0000000..a88d195 --- /dev/null +++ b/src/Core/Log.hpp @@ -0,0 +1,63 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 +// + +#pragma once + +namespace App { + +class Log { + public: + Log(const Log&) = delete; + Log(const Log&&) = delete; + Log& operator=(const Log&) = delete; + Log& operator=(const Log&&) = delete; + ~Log() = default; + + static std::shared_ptr& logger() { + return get().m_logger; + } + + private: + // The constructor shall not be deleted but used to bootstrap the logger. Ignoring + // the lint warning is ignoring doing `Log() = delete`. + // NOLINTNEXTLINE + Log(); + + static Log& get() { + static Log instance{}; + return instance; + } + + std::shared_ptr m_logger; +}; + +} // namespace App + +#ifndef APP_DEACTIVATE_LOGGING + +#if DEBUG +#define APP_TRACE(...) ::App::Log::logger()->trace(__VA_ARGS__) +#define APP_DEBUG(...) ::App::Log::logger()->debug(__VA_ARGS__) +#else +#define APP_TRACE(...) +#define APP_DEBUG(...) +#endif + +#define APP_INFO(...) ::App::Log::logger()->info(__VA_ARGS__) +#define APP_WARN(...) ::App::Log::logger()->warn(__VA_ARGS__) +#define APP_ERROR(...) ::App::Log::logger()->error(__VA_ARGS__) +#define APP_FATAL(...) ::App::Log::logger()->fatal(__VA_ARGS__) + +#else + +#define APP_TRACE(...) +#define APP_DEBUG(...) +#define APP_INFO(...) +#define APP_WARN(...) +#define APP_ERROR(...) +#define APP_FATAL(...) + +#endif diff --git a/src/Core/Resources.hpp b/src/Core/Resources.hpp new file mode 100644 index 0000000..c74d2dd --- /dev/null +++ b/src/Core/Resources.hpp @@ -0,0 +1,17 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 +// + +#pragma once + +namespace App { + +class Resources { + public: + [[nodiscard]] static std::filesystem::path resource_path(const std::filesystem::path& file_path); + [[nodiscard]] static std::filesystem::path font_path(const std::string_view& font_file); +}; + +} // namespace App diff --git a/src/Core/Window.cpp b/src/Core/Window.cpp new file mode 100644 index 0000000..ed3a75e --- /dev/null +++ b/src/Core/Window.cpp @@ -0,0 +1,62 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 +// + +#include + +#include "Window.hpp" + +#include "Debug/Instrumentor.hpp" +#include "DPIHandler.hpp" +#include "Log.hpp" + +namespace App { + +Window::Window(const Settings& settings) { + APP_PROFILE_FUNCTION(); + + const auto window_flags{ + static_cast(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI)}; + const WindowSize size{DPIHandler::get_dpi_aware_window_size(settings)}; + + m_window = SDL_CreateWindow(settings.title.c_str(), + SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, + size.width, + size.height, + window_flags); + + auto renderer_flags{ + static_cast(SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED)}; + m_renderer = SDL_CreateRenderer(m_window, -1, renderer_flags); + + if (m_renderer == nullptr) { + APP_ERROR("Error creating SDL_Renderer!"); + return; + } + + SDL_RendererInfo info; + SDL_GetRendererInfo(m_renderer, &info); + DPIHandler::set_render_scale(m_renderer); + + APP_DEBUG("Current SDL_Renderer: {}", info.name); +} + +Window::~Window() { + APP_PROFILE_FUNCTION(); + + SDL_DestroyRenderer(m_renderer); + SDL_DestroyWindow(m_window); +} + +SDL_Window* Window::get_native_window() const { + return m_window; +} + +SDL_Renderer* Window::get_native_renderer() const { + return m_renderer; +} + +} // namespace App diff --git a/src/Core/Window.hpp b/src/Core/Window.hpp new file mode 100644 index 0000000..6fd4788 --- /dev/null +++ b/src/Core/Window.hpp @@ -0,0 +1,35 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 +// + +#pragma once + +namespace App { + +class Window { + public: + struct Settings { + std::string title; + const int width{1280}; + const int height{720}; + }; + + explicit Window(const Settings& settings); + ~Window(); + + Window(const Window&) = delete; + Window(Window&&) = delete; + Window& operator=(Window other) = delete; + Window& operator=(Window&& other) = delete; + + [[nodiscard]] SDL_Window* get_native_window() const; + [[nodiscard]] SDL_Renderer* get_native_renderer() const; + + private: + SDL_Window* m_window{nullptr}; + SDL_Renderer* m_renderer{nullptr}; +}; + +} // namespace App diff --git a/src/ArchiveDialog.cpp b/src/G1AT/ArchiveDialog.cpp similarity index 70% rename from src/ArchiveDialog.cpp rename to src/G1AT/ArchiveDialog.cpp index 4c72658..703c8d3 100644 --- a/src/ArchiveDialog.cpp +++ b/src/G1AT/ArchiveDialog.cpp @@ -4,10 +4,12 @@ // SPDX-License-Identifier: EUPL-1.2 // -#include "Precompiled.hpp" +#include #include "ArchiveDialog.hpp" +#include "Utils.hpp" + bool ArchiveDirectory::Clear(const bool retVal) { directories.clear(); @@ -155,18 +157,16 @@ void ArchiveDirectory::DrawTree(const StringView8CI &thisPath) const if (!thisPath.empty() && !ImGui::TreeNode(String8(thisPath).c_str())) return; - const auto checkOriginality = Options::Get().common.checkOriginality; - for (const auto& [directoryPath, directory] : directories) { if (directory.IsDirty()) ImGui::PushStyleColor(ImGuiCol_Text, ImVec4{1.0f, 1.0f, 0.0f, 1.0f}); - else if (checkOriginality && !directory.IsOriginal()) + else if (!directory.IsOriginal()) ImGui::PushStyleColor(ImGuiCol_Text, ImVec4{0.0f, 1.0f, 0.0f, 1.0f}); directory.DrawTree(directoryPath); - if (directory.IsDirty() || (checkOriginality && !directory.IsOriginal())) + if (directory.IsDirty() || !directory.IsOriginal()) ImGui::PopStyleColor(); } @@ -174,7 +174,7 @@ void ArchiveDirectory::DrawTree(const StringView8CI &thisPath) const { if (file.dirty) ImGui::PushStyleColor(ImGuiCol_Text, ImVec4{1.0f, 1.0f, 0.0f, 1.0f}); - else if (checkOriginality && !file.original) + else if (!file.original) ImGui::PushStyleColor(ImGuiCol_Text, ImVec4{0.0f, 1.0f, 0.0f, 1.0f}); ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0, 0, 0, 0)); @@ -188,7 +188,7 @@ void ArchiveDirectory::DrawTree(const StringView8CI &thisPath) const ImGui::PopStyleVar(2); ImGui::PopStyleColor(3); - if (file.dirty || (checkOriginality && !file.original)) + if (file.dirty || !file.original) ImGui::PopStyleColor(); } @@ -200,6 +200,7 @@ bool ArchiveDialog::Clear(const bool retVal) { path.clear(); archiveRoot.Clear(); + archivePaths.clear(); return retVal; } @@ -209,9 +210,9 @@ bool ArchiveDialog::Load(const StringView8CI &loadPath) if (loadPath.empty()) return false; - GlyphRangesBuilder::Get().AddText(loadPath); + g_GlyphRangesBuilder.AddText(loadPath); - progressMessage = LocalizationManager::Get().Localize("ARCHIVE_DIALOG_LOAD_PROGRESS_READING_ARCHIVE"); + progressMessage = g_LocalizationManager.Localize("ARCHIVE_DIALOG_LOAD_PROGRESS_READING_ARCHIVE"); progressNext = 0; progressNextTotal = 1; @@ -238,7 +239,7 @@ bool ArchiveDialog::Load(const StringView8CI &loadPath) // TODO - this is causing a lot of synchronizations at the end of loading // best would be to do this on the main thread for (const auto& archivePath : archivePaths) - GlyphRangesBuilder::Get().AddText(archivePath); + g_GlyphRangesBuilder.AddText(archivePath); path = loadPath; } @@ -252,17 +253,12 @@ bool ArchiveDialog::Load(const StringView8CI &loadPath) return true; } -bool ArchiveDialog::GetAndLoad(const StringView8CI &filters, const StringView8CI &defaultFilename) -{ - return Load(OpenFileDialog(filters, defaultFilename)); -} - bool ArchiveDialog::Import(const StringView8CI &importFolderPath) { if (importFolderPath.empty()) return false; - progressMessage = LocalizationManager::Get().Localize("ARCHIVE_DIALOG_IMPORT_PROGRESS_IMPORTING_DATA"); + progressMessage = g_LocalizationManager.Localize("ARCHIVE_DIALOG_IMPORT_PROGRESS_IMPORTING_DATA"); progressNext = 0; progressNextTotal = 1; @@ -284,7 +280,7 @@ bool ArchiveDialog::Import(const StringView8CI &importFolderPath) { { std::unique_lock progressMessageLock(progressMessageMutex); - progressMessage = LocalizationManager::Get().LocalizeFormat("ARCHIVE_DIALOG_IMPORT_PROGRESS_IMPORTING_FILE", String8(relative(importFilePath.path(), importFolderPath.path()))); + progressMessage = g_LocalizationManager.LocalizeFormat("ARCHIVE_DIALOG_IMPORT_PROGRESS_IMPORTING_FILE", String8(relative(importFilePath.path(), importFolderPath.path()))); ++progressNext; } @@ -298,17 +294,12 @@ bool ArchiveDialog::Import(const StringView8CI &importFolderPath) return true; } -bool ArchiveDialog::GetAndImport() -{ - return Import(BrowseDirectoryDialog()); -} - bool ArchiveDialog::Export(const StringView8CI &exportFolderPath) { if (exportFolderPath.empty()) return false; - progressMessage = LocalizationManager::Get().Localize("ARCHIVE_DIALOG_EXPORT_PROGRESS_EXPORTING_DATA"); + progressMessage = g_LocalizationManager.Localize("ARCHIVE_DIALOG_EXPORT_PROGRESS_EXPORTING_DATA"); progressNext = 0; progressNextTotal = 1; @@ -328,7 +319,7 @@ bool ArchiveDialog::Export(const StringView8CI &exportFolderPath) { { std::unique_lock progressMessageLock(progressMessageMutex); - progressMessage = LocalizationManager::Get().LocalizeFormat("ARCHIVE_DIALOG_IMPORT_PROGRESS_EXPORTING_FILE", exportFilePath); + progressMessage = g_LocalizationManager.LocalizeFormat("ARCHIVE_DIALOG_IMPORT_PROGRESS_EXPORTING_FILE", exportFilePath); ++progressNext; } @@ -342,19 +333,14 @@ bool ArchiveDialog::Export(const StringView8CI &exportFolderPath) return true; } -bool ArchiveDialog::GetAndExport() -{ - return Export(BrowseDirectoryDialog()); -} - bool ArchiveDialog::Save(const StringView8CI &savePath, bool async) { if (savePath.empty()) return false; - GlyphRangesBuilder::Get().AddText(savePath); + g_GlyphRangesBuilder.AddText(savePath); - progressMessage = LocalizationManager::Get().Localize("ARCHIVE_DIALOG_SAVE_PROGRESS_SAVING_ARCHIVE"); + progressMessage = g_LocalizationManager.Localize("ARCHIVE_DIALOG_SAVE_PROGRESS_SAVING_ARCHIVE"); progressNext = 0; progressNextTotal = 1; @@ -383,29 +369,24 @@ bool ArchiveDialog::Save(const StringView8CI &savePath, bool async) return true; } -bool ArchiveDialog::GetAndSave(const StringView8CI &filters, const StringView8CI &defaultFilename) -{ - return Save(SaveFileDialog(filters, defaultFilename), true); -} - int32_t ArchiveDialog::UnsavedChangesPopup() const { if (!archiveRoot.IsDirty()) return 0; - const auto msgBoxResult = DisplayWarning(LocalizationManager::Get().Localize("ARCHIVE_DIALOG_UNSAVED_CHANGES_MESSAGE"), - LocalizationManager::Get().Localize("ARCHIVE_DIALOG_UNSAVED_CHANGES_TITLE"), true); + const auto msgBoxResult = DisplayWarning(g_LocalizationManager.Localize("ARCHIVE_DIALOG_UNSAVED_CHANGES_MESSAGE"), + g_LocalizationManager.Localize("ARCHIVE_DIALOG_UNSAVED_CHANGES_TITLE"), true); switch (msgBoxResult) { case IDYES: { return 1; } - default: - case IDCLOSE: case IDNO: { return 0; } + default: + case IDCLOSE: case IDCANCEL: { return -1; } @@ -417,6 +398,11 @@ StringView8CI ArchiveDialog::GetPath() const return path; } +bool ArchiveDialog::IsAllowed() const +{ + return IsSaveAllowed() || IsExportAllowed() || IsImportAllowed(); +} + bool ArchiveDialog::IsInProgress() const { return progressTask.valid(); @@ -457,7 +443,7 @@ void ArchiveDialog::CleanOriginal() archiveRoot.CleanOriginal(); } -void ArchiveDialog::DrawBaseDialog(const StringView8CI &dialogName, const StringView8CI &filters, const StringView8CI &defaultFilename) +int32_t ArchiveDialog::DrawBaseDialog() { auto progressActive = IsInProgress(); if (progressActive) @@ -471,80 +457,52 @@ void ArchiveDialog::DrawBaseDialog(const StringView8CI &dialogName, const String } } - auto wasProgressActive = progressActive; - const auto archivePath = progressActive ? "" : path; + const auto displayPath = archivePath.empty() ? g_LocalizationManager.Localize("ARCHIVE_DIALOG_PROCESSING") : String8(archivePath); + bool* openedPtr = progressActive ? nullptr : &opened; - if (!ImGui::BeginTabItem(dialogName.c_str())) - return; - - const auto itemWidth = GetAlignedItemWidth(5); - - if (progressActive) - ImGui::BeginDisabled(); - - if (ImGui::Button(LocalizationManager::Get().Localize("ARCHIVE_DIALOG_OPEN").c_str(), ImVec2(itemWidth, 0))) - GetAndLoad(filters, defaultFilename); - - progressActive = IsInProgress(); - if (!wasProgressActive && (progressActive || archivePath.empty())) - { - wasProgressActive |= progressActive; - ImGui::BeginDisabled(); - } - - ImGui::SameLine(); - - if (ImGui::Button(LocalizationManager::Get().Localize("ARCHIVE_DIALOG_SAVE").c_str(), ImVec2(itemWidth, 0))) - Save(archivePath, true); - - progressActive = IsInProgress(); - if (!archivePath.empty() && !wasProgressActive && progressActive) - { - wasProgressActive = true; - ImGui::BeginDisabled(); - } - - ImGui::SameLine(); - - if (ImGui::Button(LocalizationManager::Get().Localize("ARCHIVE_DIALOG_SAVE_INTO").c_str(), ImVec2(itemWidth, 0))) - GetAndSave(filters, defaultFilename); - - progressActive = IsInProgress(); - if (!archivePath.empty() && !wasProgressActive && progressActive) - { - wasProgressActive = true; - ImGui::BeginDisabled(); - } + const auto shouldExit = [&] + { + if (!opened) + { + if (progressActive) + { + opened = true; + return false; + } + + switch (UnsavedChangesPopup()) + { + case 1: { + Save(GetPath(), false); + return true; + } + case 0: { + return true; + } + default: + case -1: { + opened = true; + return false; + } + } + } - ImGui::SameLine(); + return false; + }; - if (ImGui::Button(LocalizationManager::Get().Localize("ARCHIVE_DIALOG_EXPORT_TO").c_str(), ImVec2(itemWidth, 0))) - GetAndExport(); + if (shouldExit()) + return -1; - progressActive = IsInProgress(); - if (!archivePath.empty() && !wasProgressActive && progressActive) + if (!ImGui::Begin(std::format("{}##{}", displayPath, (void*)this).c_str(), openedPtr)) { - wasProgressActive = true; - ImGui::BeginDisabled(); - } + ImGui::End(); - ImGui::SameLine(); - - if (ImGui::Button(LocalizationManager::Get().Localize("ARCHIVE_DIALOG_IMPORT_FROM").c_str(), ImVec2(itemWidth, 0))) - GetAndImport(); - - progressActive = IsInProgress(); - if (!archivePath.empty() && !wasProgressActive && progressActive) - { - wasProgressActive = true; - ImGui::BeginDisabled(); + return shouldExit() ? -1 : 0; } - if (wasProgressActive) + if (progressActive) { - ImGui::EndDisabled(); - std::unique_lock progressMessageLock(progressMessageMutex); auto progressTotal = progressNextTotal.load(); @@ -552,7 +510,7 @@ void ArchiveDialog::DrawBaseDialog(const StringView8CI &dialogName, const String { auto progressCurrent = progressNext.load(); - const auto& progressSummary = LocalizationManager::Get().LocalizeFormat("ARCHIVE_DIALOG_PROGRESS_SUMMARY", progressCurrent, progressTotal); + const auto& progressSummary = g_LocalizationManager.LocalizeFormat("ARCHIVE_DIALOG_PROGRESS_SUMMARY", progressCurrent, progressTotal); if (progressMessage.empty()) ImGui::TextUnformatted(progressSummary.c_str()); else @@ -561,24 +519,19 @@ void ArchiveDialog::DrawBaseDialog(const StringView8CI &dialogName, const String else if (!progressMessage.empty()) ImGui::TextUnformatted(progressMessage.c_str()); } - else + else if (!archivePath.empty()) { - if (archivePath.empty()) - { - ImGui::EndDisabled(); - ImGui::TextUnformatted(LocalizationManager::Get().Localize("ARCHIVE_DIALOG_NO_ARCHIVE").c_str()); - } - else - ImGui::TextUnformatted(LocalizationManager::Get().LocalizeFormat("ARCHIVE_DIALOG_LOADED_ARCHIVE", archivePath).c_str()); - - ImGui::Separator(); - - ImGui::BeginChild("##FileList", {}, false, ImGuiWindowFlags_HorizontalScrollbar); - - archiveRoot.DrawTree(); + if (ImGui::BeginChild("##FileList", {}, false, ImGuiWindowFlags_HorizontalScrollbar)) + archiveRoot.DrawTree(); ImGui::EndChild(); } + else + ImGui::TextUnformatted(g_LocalizationManager.Localize("ARCHIVE_DIALOG_NO_ARCHIVE").c_str()); + + const auto isFocused = ImGui::IsWindowFocused(); + + ImGui::End(); - ImGui::EndTabItem(); + return isFocused ? 1 : 0; } diff --git a/src/ArchiveDialog.hpp b/src/G1AT/ArchiveDialog.hpp similarity index 87% rename from src/ArchiveDialog.hpp rename to src/G1AT/ArchiveDialog.hpp index 0a501fe..5b4e30d 100644 --- a/src/ArchiveDialog.hpp +++ b/src/G1AT/ArchiveDialog.hpp @@ -6,6 +6,8 @@ #pragma once +#include "Options.hpp" + struct ArchiveFile { bool dirty = false; @@ -49,26 +51,29 @@ class ArchiveDialog virtual bool LoadImpl(const StringView8CI &loadPath, const Options &options) = 0; bool Load(const StringView8CI &loadPath); - bool GetAndLoad(const StringView8CI &filters, const StringView8CI &defaultFilename); virtual bool ImportSingle(const StringView8CI &importFolderPath, const StringView8CI &importFilePath, const Options &options) = 0; bool Import(const StringView8CI &importFolderPath); - bool GetAndImport(); virtual bool ExportSingle(const StringView8CI &exportFolderPath, const StringView8CI &exportFilePath, const Options &options) const = 0; bool Export(const StringView8CI &exportFolderPath); - bool GetAndExport(); virtual bool SaveImpl(const StringView8CI &savePath, const Options &options) = 0; bool Save(const StringView8CI &savePath, bool async); - bool GetAndSave(const StringView8CI &filters, const StringView8CI &defaultFilename); int32_t UnsavedChangesPopup() const; - virtual void DrawDialog() = 0; + virtual int32_t DrawDialog() = 0; StringView8CI GetPath() const; + virtual bool IsSaveAllowed() const = 0; + virtual bool IsExportAllowed() const = 0; + virtual bool IsImportAllowed() const = 0; + + virtual const std::vector>& GetSaveFilter() const = 0; + + bool IsAllowed() const; bool IsInProgress() const; ArchiveDirectory& GetDirectory(const StringView8CI &searchPath); @@ -82,7 +87,7 @@ class ArchiveDialog void CleanOriginal(); protected: - void DrawBaseDialog(const StringView8CI &dialogName, const StringView8CI &filters, const StringView8CI &defaultFilename); + int32_t DrawBaseDialog(); String8CI path; @@ -92,6 +97,8 @@ class ArchiveDialog std::atomic_uint64_t progressNextTotal = 0; std::future progressTask; + bool opened = true; + private: ArchiveDirectory archiveRoot; OrderedSet archivePaths; diff --git a/src/Hitman1Dialog.cpp b/src/G1AT/Hitman1Dialog.cpp similarity index 55% rename from src/Hitman1Dialog.cpp rename to src/G1AT/Hitman1Dialog.cpp index ec82332..aca7da4 100644 --- a/src/Hitman1Dialog.cpp +++ b/src/G1AT/Hitman1Dialog.cpp @@ -4,10 +4,12 @@ // SPDX-License-Identifier: EUPL-1.2 // -#include "Precompiled.hpp" +#include #include "Hitman1Dialog.hpp" +#include "Utils.hpp" + bool Hitman1Dialog::Clear(const bool retVal) { indexToKey.clear(); @@ -21,17 +23,18 @@ bool Hitman1Dialog::LoadImpl(const StringView8CI &loadPathView, const Options &o const auto loadPath = loadPathView.path(); Clear(); - const auto archiveBinFilePath = ChangeExtension(loadPathView, ".bin"); - if (!exists(archiveBinFilePath.path())) + auto archiveBinFilePath = loadPathView.path(); + archiveBinFilePath.replace_extension(L".bin"); + if (!exists(archiveBinFilePath)) { - DisplayError(LocalizationManager::Get().Localize("HITMAN_1_DIALOG_ERROR_MISSING_BIN")); + DisplayError(g_LocalizationManager.Localize("HITMAN_1_DIALOG_ERROR_MISSING_BIN")); return false; } const auto oldSync = std::ios_base::sync_with_stdio(false); - const auto archiveBin = ReadWholeBinaryFile(archiveBinFilePath); - auto archiveIdx = ReadWholeTextFile(String8CI(loadPath)).native(); + const auto archiveBin = ReadWholeBinaryFile(String8(archiveBinFilePath)); + auto archiveIdx = ReadWholeTextFile(loadPathView).native(); auto archiveIdxScan = scn::make_result(archiveIdx); size_t archiveBinOffset = 0; @@ -55,7 +58,7 @@ bool Hitman1Dialog::LoadImpl(const StringView8CI &loadPathView, const Options &o auto& file = GetFile(entryPath); - auto [fileMapIt, inserted] = fileMap.try_emplace(file.path, HitmanFile{}); + auto [fileMapIt, inserted] = fileMap.try_emplace(file.path, HitmanFile{file.path}); if (!inserted) return Clear(false); @@ -66,7 +69,7 @@ bool Hitman1Dialog::LoadImpl(const StringView8CI &loadPathView, const Options &o std::vector fileData(dataSize, 0); std::memcpy(fileData.data(), archiveBin.data() + archiveBinOffset, dataSize); - if (!ImportSingleHitmanFile(fileMapIt->second, file.path, fileData, false, options)) + if (!ImportSingleHitmanFile(fileMapIt->second, fileData, false, options)) return Clear(false); archiveBinOffset += dataSize; @@ -77,20 +80,19 @@ bool Hitman1Dialog::LoadImpl(const StringView8CI &loadPathView, const Options &o std::ios_base::sync_with_stdio(oldSync); - if (!options.common.checkOriginality) - return true; - auto dataPath = GetProgramPath().path(); if (dataPath.empty()) return Clear(false); dataPath /= L"data"; dataPath /= L"records"; - dataPath /= L"h1"; + dataPath /= L"h1_"; - originalDataPath = dataPath; + originalDataPathPrefix = dataPath; + originalDataID = XXH3_64bits(archiveBin.data(), archiveBin.size()); + originalDataParentID = 0; - if (!LoadOriginalData()) + if (!LoadOriginalData(options)) return Clear(false); return true; @@ -98,37 +100,38 @@ bool Hitman1Dialog::LoadImpl(const StringView8CI &loadPathView, const Options &o bool Hitman1Dialog::ImportSingle(const StringView8CI &importFolderPathView, const StringView8CI &importFilePathView, const Options &options) { - auto filePath = String8CI(relative(importFilePathView.path(), importFolderPathView.path())); + auto filePath = relative(importFilePathView.path(), importFolderPathView.path()); auto fileIt = fileMap.find(filePath); if (fileIt == fileMap.end()) { - const StringView8CI nextExtension(filePath.path().extension() == StringViewWCI(L".wav") ? ".ogg" : ".wav"); - filePath = ChangeExtension(filePath, nextExtension); + filePath.replace_extension(filePath.extension() == StringViewWCI(L".wav") ? L".ogg" : L".wav"); fileIt = fileMap.find(filePath); if (fileIt == fileMap.end()) { - DisplayWarning(LocalizationManager::Get().LocalizeFormat("HITMAN_DIALOG_WARNING_MISSING_FILE", importFilePathView), - LocalizationManager::Get().Localize("MESSAGEBOX_WARNING_GENERIC_TITLE"), false, options); + DisplayWarning(g_LocalizationManager.LocalizeFormat("HITMAN_DIALOG_WARNING_MISSING_FILE", importFilePathView), + g_LocalizationManager.Localize("MESSAGEBOX_WARNING_GENERIC_TITLE"), false, options); return false; } } - if (!ImportSingleHitmanFile(fileIt->second, filePath, importFilePathView, options)) + if (!ImportSingleHitmanFile(fileIt->second, importFilePathView, options)) return false; return true; } -bool Hitman1Dialog::SaveImpl(const StringView8CI &savePathView, const Options &) +bool Hitman1Dialog::SaveImpl(const StringView8CI &savePathView, const Options &options) { - const auto archiveBinFilePath = ChangeExtension(savePathView, ".bin"); + const auto archiveIdxFilePath = savePathView.path(); + auto archiveBinFilePath = archiveIdxFilePath; + archiveBinFilePath.replace_extension(L".bin"); const auto oldSync = std::ios_base::sync_with_stdio(false); - std::ofstream archiveIdx(savePathView.path(), std::ios::trunc); - std::ofstream archiveBin(archiveBinFilePath.path(), std::ios::binary | std::ios::trunc); + std::ofstream archiveIdx(archiveIdxFilePath, std::ios::trunc); + std::ofstream archiveBin(archiveBinFilePath, std::ios::binary | std::ios::trunc); - thread_local static std::vector exportBytes; + std::vector exportBytes; for (const auto &filePath : indexToKey) { auto fileIt = fileMap.find(filePath); @@ -139,7 +142,7 @@ bool Hitman1Dialog::SaveImpl(const StringView8CI &savePathView, const Options &) if (lastModifiedDateIt == lastModifiedDatesMap.end()) return false; - fileIt->second.Export(exportBytes); + fileIt->second.ExportNative(exportBytes, options); archiveIdx << std::format("-rw-rw-r-- 1 zope {:12d} {} {}\n", exportBytes.size(), lastModifiedDateIt->second, filePath); @@ -148,12 +151,45 @@ bool Hitman1Dialog::SaveImpl(const StringView8CI &savePathView, const Options &) GetFile(filePath).dirty = false; } + archiveBin.close(); + archiveIdx.close(); + std::ios_base::sync_with_stdio(oldSync); + originalDataParentID = originalDataID; + + const auto archiveBinData = ReadWholeBinaryFile(String8CI(archiveBinFilePath)); + originalDataID = XXH3_64bits(archiveBinData.data(), archiveBinData.size()); + + if (!LoadOriginalData(options)) + return Clear(false); + return true; } -void Hitman1Dialog::DrawDialog() +int32_t Hitman1Dialog::DrawDialog() { - DrawHitmanDialog("Codename 47", "Hitman 1 Speech (*.idx)\0*.idx\0", "English.idx"); + return DrawHitmanDialog(); +} + +const std::vector>& Hitman1Dialog::GetOpenFilter() +{ + static std::vector> filters; + if (!filters.empty()) + return filters; + + filters.emplace_back("FILE_DIALOG_FILTER_HITMAN1_SPEECH", "*.idx"); + + return filters; +} + +const std::vector>& Hitman1Dialog::GetSaveFilter() const +{ + static std::vector> filters; + if (!filters.empty()) + return filters; + + filters.emplace_back("FILE_DIALOG_FILTER_HITMAN1_SPEECH", "*.idx"); + + return filters; } diff --git a/src/Hitman1Dialog.hpp b/src/G1AT/Hitman1Dialog.hpp similarity index 72% rename from src/Hitman1Dialog.hpp rename to src/G1AT/Hitman1Dialog.hpp index c3e6994..5aef427 100644 --- a/src/Hitman1Dialog.hpp +++ b/src/G1AT/Hitman1Dialog.hpp @@ -8,7 +8,7 @@ #include "HitmanDialog.hpp" -class Hitman1Dialog final : public HitmanDialog, public Singleton +class Hitman1Dialog final : public HitmanDialog { public: bool Clear(bool retVal = false) override; @@ -19,7 +19,11 @@ class Hitman1Dialog final : public HitmanDialog, public Singleton bool SaveImpl(const StringView8CI &savePath, const Options &options) override; - void DrawDialog() override; + int32_t DrawDialog() override; + + static const std::vector>& GetOpenFilter(); + + const std::vector>& GetSaveFilter() const override; std::vector indexToKey; diff --git a/src/Hitman23Dialog.cpp b/src/G1AT/Hitman23Dialog.cpp similarity index 76% rename from src/Hitman23Dialog.cpp rename to src/G1AT/Hitman23Dialog.cpp index fc9f700..549c9cb 100644 --- a/src/Hitman23Dialog.cpp +++ b/src/G1AT/Hitman23Dialog.cpp @@ -3,11 +3,15 @@ // Copyright © 2015-2023 Feldarian Softworks. All rights reserved. // SPDX-License-Identifier: EUPL-1.2 // +// TODO - make sure that dialogs shared between multiple games do not check bytes of files directly (contents different == bytes different) +// -#include "Precompiled.hpp" +#include #include "Hitman23Dialog.hpp" +#include "Utils.hpp" + HitmanSoundRecord Hitman23WHDRecord::ToHitmanSoundRecord() const { return { @@ -19,7 +23,7 @@ HitmanSoundRecord Hitman23WHDRecord::ToHitmanSoundRecord() const static_cast(bitsPerSample), static_cast(channels), static_cast(blockAlign), - static_cast(fmtExtra) + static_cast(samplesPerBlock) }; } @@ -33,7 +37,7 @@ void Hitman23WHDRecord::FromHitmanSoundRecord(const HitmanSoundRecord &soundReco channels = soundRecord.channels; samplesCount = soundRecord.dataSizeUncompressed / sizeof(int16_t); blockAlign = soundRecord.blockAlign; - fmtExtra = soundRecord.fmtExtra; + samplesPerBlock = soundRecord.samplesPerBlock; } bool Hitman23WAVFile::Clear(const bool retVal) @@ -46,10 +50,9 @@ bool Hitman23WAVFile::Clear(const bool retVal) return retVal; } -bool Hitman23WAVFile::Load(const StringView8CI &loadPath, const OrderedMap &whdRecordsMap, +bool Hitman23WAVFile::Load(const std::vector &wavData, const OrderedMap &whdRecordsMap, OrderedMap& fileMap, const bool isMissionWAV) { - const auto wavData = ReadWholeBinaryFile(loadPath); if (wavData.empty()) return Clear(false); @@ -99,8 +102,6 @@ bool Hitman23WAVFile::Load(const StringView8CI &loadPath, const OrderedMap &whdRecordsMap, + OrderedMap& fileMap, const bool isMissionWAV) +{ + if (!Load(ReadWholeBinaryFile(loadPath), whdRecordsMap, fileMap, isMissionWAV)) + return false; + path = loadPath; return true; } @@ -221,7 +236,7 @@ bool Hitman23WHDFile::Load(Hitman23Dialog& archiveDialog, const StringView8CI &l if (whdRecord->dataInStreams == 0) filePath = relative(loadPathView.path(), archiveDialog.basePath.path()) / filePath.path(); - else + else if (!filePath.native().starts_with("Streams")) filePath = L"Streams" / filePathNative; auto& file = archiveDialog.GetFile(filePath); @@ -230,7 +245,9 @@ bool Hitman23WHDFile::Load(Hitman23Dialog& archiveDialog, const StringView8CI &l return Clear(false); archiveDialog.whdRecordsMap[file.path].emplace_back(whdRecord); - archiveDialog.fileMap[file.path].archiveRecord = whdRecord->ToHitmanSoundRecord(); + + [[maybe_unused]] const auto [fileMapIt, fileMapEmplaced] = archiveDialog.fileMap.try_emplace(file.path, HitmanFile{file.path, whdRecord->ToHitmanSoundRecord()}); + assert(whdRecord->dataInStreams || fileMapEmplaced); } path = loadPathView; @@ -276,24 +293,23 @@ bool Hitman23Dialog::Clear(const bool retVal) bool Hitman23Dialog::ImportSingle(const StringView8CI &importFolderPathView, const StringView8CI &importFilePathView, const Options &options) { - auto filePath = String8CI(relative(importFilePathView.path(), importFolderPathView.path())); + auto filePath = relative(importFilePathView.path(), importFolderPathView.path()); auto fileIt = fileMap.find(filePath); auto whdRecordsIt = whdRecordsMap.find(filePath); if (fileIt == fileMap.end() || whdRecordsIt == whdRecordsMap.end()) { - const StringView8CI nextExtension = filePath.path().extension() == StringViewWCI(L".wav") ? ".ogg" : ".wav"; - filePath = ChangeExtension(filePath, nextExtension); + filePath.replace_extension(filePath.extension() == StringViewWCI(L".wav") ? L".ogg" : L".wav"); fileIt = fileMap.find(filePath); whdRecordsIt = whdRecordsMap.find(filePath); if (fileIt == fileMap.end() || whdRecordsIt == whdRecordsMap.end()) { - DisplayWarning(LocalizationManager::Get().LocalizeFormat("HITMAN_DIALOG_WARNING_MISSING_FILE", importFilePathView), - LocalizationManager::Get().Localize("MESSAGEBOX_WARNING_GENERIC_TITLE"), false, options); + DisplayWarning(g_LocalizationManager.LocalizeFormat("HITMAN_DIALOG_WARNING_MISSING_FILE", importFilePathView), + g_LocalizationManager.Localize("MESSAGEBOX_WARNING_GENERIC_TITLE"), false, options); return false; } } - if (!ImportSingleHitmanFile(fileIt->second, filePath, importFilePathView, options)) + if (!ImportSingleHitmanFile(fileIt->second, importFilePathView, options)) return false; for (auto* whdRecord : whdRecordsIt->second) @@ -310,7 +326,7 @@ bool Hitman23Dialog::LoadImpl(const StringView8CI &loadPathView, const Options & const auto scenesPath = rootPath / L"Scenes"; if (!exists(scenesPath)) { - DisplayError(LocalizationManager::Get().Localize("HITMAN_23_DIALOG_ERROR_MISSING_SCENES")); + DisplayError(g_LocalizationManager.Localize("HITMAN_23_DIALOG_ERROR_MISSING_SCENES")); return false; } @@ -336,33 +352,33 @@ bool Hitman23Dialog::LoadImpl(const StringView8CI &loadPathView, const Options & assert(res.second || (res.first->second->dataInStreams && res.first->second->dataInStreams == whdRecord->dataInStreams && res.first->second->dataOffset == whdRecord->dataOffset)); } - if (!wavFiles.emplace_back().Load(ChangeExtension(whdFile.path, ".wav"), whdFile.recordMap, fileMap, true)) + if (!wavFiles.emplace_back().Load(String8CI(whdFile.path.path().replace_extension(L".wav")), whdFile.recordMap, fileMap, true)) return Clear(false); } - if (!streamsWAV.Load(loadPathView, allWHDRecords, fileMap, false)) + const auto streamsWAVData = ReadWholeBinaryFile(loadPathView); + if (!streamsWAV.Load(streamsWAVData, allWHDRecords, fileMap, false)) return Clear(false); - if (!options.common.checkOriginality) - return true; - auto dataPath = GetProgramPath().path(); if (dataPath.empty()) return Clear(false); dataPath /= L"data"; dataPath /= L"records"; - dataPath /= streamsWAV.recordMap.at(0).data[0] == 0x6F ? L"h2" : L"h3"; + dataPath /= L"h23_"; - originalDataPath = dataPath; + originalDataPathPrefix = dataPath; + originalDataID = XXH3_64bits(streamsWAVData.data(), streamsWAVData.size()); + originalDataParentID = 0; - if (!LoadOriginalData()) + if (!LoadOriginalData(options)) return Clear(false); return true; } -bool Hitman23Dialog::SaveImpl(const StringView8CI &savePathView, const Options &) +bool Hitman23Dialog::SaveImpl(const StringView8CI &savePathView, const Options &options) { const auto newBasePath = savePathView.path().parent_path(); @@ -378,10 +394,40 @@ bool Hitman23Dialog::SaveImpl(const StringView8CI &savePathView, const Options & CleanDirty(); + originalDataParentID = originalDataID; + + const auto streamsWAVData = ReadWholeBinaryFile(savePathView); + originalDataID = XXH3_64bits(streamsWAVData.data(), streamsWAVData.size()); + + if (!LoadOriginalData(options)) + return Clear(false); + return true; } -void Hitman23Dialog::DrawDialog() +int32_t Hitman23Dialog::DrawDialog() { - DrawHitmanDialog("Silent Assassin / Contracts", "Hitman 2/3 Streams (streams.wav)\0streams.wav\0", "streams.wav"); + return DrawHitmanDialog(); +} + +const std::vector>& Hitman23Dialog::GetOpenFilter() +{ + static std::vector> filters; + if (!filters.empty()) + return filters; + + filters.emplace_back("FILE_DIALOG_FILTER_HITMAN23_STREAMS", "streams.wav"); + + return filters; +} + +const std::vector>& Hitman23Dialog::GetSaveFilter() const +{ + static std::vector> filters; + if (!filters.empty()) + return filters; + + filters.emplace_back("FILE_DIALOG_FILTER_HITMAN23_STREAMS", "streams.wav"); + + return filters; } diff --git a/src/Hitman23Dialog.hpp b/src/G1AT/Hitman23Dialog.hpp similarity index 86% rename from src/Hitman23Dialog.hpp rename to src/G1AT/Hitman23Dialog.hpp index 3e70f0e..91664dc 100644 --- a/src/Hitman23Dialog.hpp +++ b/src/G1AT/Hitman23Dialog.hpp @@ -32,7 +32,7 @@ struct Hitman23WHDRecord uint32_t dataOffset = 0; uint32_t samplesCount = 0; // always half of dataSizeUncompressed uint32_t blockAlign = 0; - uint32_t fmtExtra = 0; // always 1 when formatTag == 1 + uint32_t samplesPerBlock = 0; // always 1 when formatTag == 1 HitmanSoundRecord ToHitmanSoundRecord() const; void FromHitmanSoundRecord(const HitmanSoundRecord& soundRecord); @@ -76,6 +76,8 @@ struct Hitman23WAVFile { bool Clear(bool retVal = false); + bool Load(const std::vector &wavData, const OrderedMap &whdRecordsMap, + OrderedMap& fileMap, bool isMissionWAV); bool Load(const StringView8CI &loadPath, const OrderedMap &whdRecordsMap, OrderedMap& fileMap, bool isMissionWAV); @@ -101,7 +103,7 @@ struct Hitman23WHDFile String8CI path; }; -class Hitman23Dialog final : public HitmanDialog, public Singleton +class Hitman23Dialog final : public HitmanDialog { public: bool Clear(bool retVal = false) override; @@ -112,7 +114,11 @@ class Hitman23Dialog final : public HitmanDialog, public Singleton>& GetOpenFilter(); + + const std::vector>& GetSaveFilter() const override; std::vector whdFiles; std::vector wavFiles; diff --git a/src/G1AT/Hitman4Dialog.cpp b/src/G1AT/Hitman4Dialog.cpp new file mode 100644 index 0000000..c80bee4 --- /dev/null +++ b/src/G1AT/Hitman4Dialog.cpp @@ -0,0 +1,902 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 +// +// TODO - GOG and Steam version have a hash conflict! Either they truly have streams file the exact same or I don't know... But it reports everything as changed! +// - workaround for now - remove "h4_" prefixed files from "data/records" before opening GOG archive... +// +// TODO - aliased entries look different in STR - do they look different in scene WAV? can they be present there? +// + +#include + +#include "Hitman4Dialog.hpp" + +#include "Utils.hpp" + +#include + +HitmanSoundRecord Hitman4WHDRecord::Hitman4WHDRecordScene::ToHitmanSoundRecord() const +{ + assert(filePathLength > 0 && filePathLength < 0x004F4850); + + const auto resBitsPerSample = static_cast(formatTag == 4096 ? 16 : bitsPerSample); + const auto resChannels = static_cast(channels); + const auto resBlockAlign = static_cast(formatTag == 4096 ? 2 * channels : blockAlign); + const auto resFmtExtra = static_cast(formatTag == 17 ? samplesPerBlock : 1); + + assert(resBlockAlign == 2 * channels || formatTag == 17); + assert(resBlockAlign != 1024 || formatTag == 17); + + return { + 0, + dataSizeUncompressed, + dataSize, + sampleRate, + formatTag, + resBitsPerSample, + resChannels, + resBlockAlign, + resFmtExtra + }; +} + +void Hitman4WHDRecord::Hitman4WHDRecordScene::FromHitmanSoundRecord(const HitmanSoundRecord &soundRecord) +{ + assert(formatTag != 4096 || formatTag == soundRecord.formatTag); + + formatTag = soundRecord.formatTag; + sampleRate = soundRecord.sampleRate; + bitsPerSample = formatTag == 4096 ? 0 : soundRecord.bitsPerSample; + dataSizeUncompressed = soundRecord.dataSizeUncompressed; + dataSize = soundRecord.dataSize; + channels = soundRecord.channels; + samplesCount = soundRecord.dataSizeUncompressed / sizeof(int16_t); + blockAlign = formatTag == 4096 ? blockAlign : soundRecord.blockAlign; + samplesPerBlock = formatTag == 4096 ? 0x004F3E93 : (formatTag == 1 ? 0xCDCDCDCD : soundRecord.samplesPerBlock); +} + +HitmanSoundRecord Hitman4WHDRecord::Hitman4WHDRecordSceneAliased::ToHitmanSoundRecord() const +{ + assert(nullByte == 0); + + const auto resBitsPerSample = static_cast(formatTag == 4096 ? 16 : bitsPerSample); + const auto resChannels = static_cast(channels); + const auto resBlockAlign = static_cast(formatTag == 4096 ? 2 * channels : blockAlign); + const auto resFmtExtra = static_cast(formatTag == 17 ? fmtExtra : 1); + + assert(resBlockAlign != 1024 || formatTag == 17); + + return { + 0, + dataSizeUncompressed, + dataSize, + sampleRate, + formatTag, + resBitsPerSample, + resChannels, + resBlockAlign, + resFmtExtra + }; +} + +void Hitman4WHDRecord::Hitman4WHDRecordSceneAliased::FromHitmanSoundRecord(const HitmanSoundRecord &soundRecord) +{ + assert(formatTag != 4096 || formatTag == soundRecord.formatTag); + + formatTag = soundRecord.formatTag; + sampleRate = soundRecord.sampleRate; + bitsPerSample = formatTag == 4096 ? 0 : soundRecord.bitsPerSample; + dataSizeUncompressed = soundRecord.dataSizeUncompressed; + dataSize = soundRecord.dataSize; + channels = soundRecord.channels; + samplesCount = soundRecord.dataSizeUncompressed / sizeof(int16_t); + blockAlign = formatTag == 4096 ? blockAlign : soundRecord.blockAlign; + fmtExtra = formatTag == 4096 ? 0x004F3E93 : (formatTag == 1 ? 0xCDCDCDCD : soundRecord.samplesPerBlock); +} + +HitmanSoundRecord Hitman4WHDRecord::Hitman4WHDRecordStreams::ToHitmanSoundRecord() const +{ + assert(id == 0x004F4850); + + const auto resBitsPerSample = static_cast(formatTag == 4096 ? 16 : bitsPerSample); + const auto resChannels = static_cast(channels); + const auto resBlockAlign = static_cast(formatTag == 4096 || formatTag == 1 ? 2 * channels : 1024); + const auto resFmtExtra = static_cast(formatTag == 17 ? fmtExtra : 1); + + assert(resBlockAlign == 2 * channels || formatTag == 17); + assert(resBlockAlign != 1024 || formatTag == 17); + + return { + 0, + dataSizeUncompressed, + dataSize, + unkC, + formatTag, + resBitsPerSample, + resChannels, + resBlockAlign, + resFmtExtra + }; +} + +void Hitman4WHDRecord::Hitman4WHDRecordStreams::FromHitmanSoundRecord(const HitmanSoundRecord &soundRecord) +{ + assert(formatTag == soundRecord.formatTag); + + formatTag = soundRecord.formatTag; + unk2C = soundRecord.sampleRate; + bitsPerSample = formatTag == 4096 ? 0 : soundRecord.bitsPerSample; + dataSizeUncompressed = soundRecord.dataSizeUncompressed; + dataSize = soundRecord.dataSize; + channels = soundRecord.channels; + samplesCount = soundRecord.dataSizeUncompressed / sizeof(int16_t); + fmtExtra = formatTag == 4096 ? 0x004F3E93 : (formatTag == 1 ? 0xCDCDCDCD : soundRecord.samplesPerBlock); +} + +HitmanSoundRecord Hitman4WHDRecord::ToHitmanSoundRecord() const +{ + assert((streams.id == 0x004F4850) == (streams.dataInStreams == 128)); + + assert(streams.formatTag != 1 || streams.bitsPerSample == 16); + assert(streams.formatTag != 17 || streams.bitsPerSample == 4); + assert(streams.formatTag != 4096 || streams.bitsPerSample == 0); + + assert(scene.formatTag != 17 || scene.blockAlign == 1024); + + assert(streams.formatTag != 17 || streams.fmtExtra == 2041); + assert(streams.formatTag != 4096 || streams.fmtExtra == 0x004F3E93); + + assert(streams.nullBytes[0] == 0); + + switch (streams.id) + { + case 0x004F4850: + return streams.ToHitmanSoundRecord(); + case 0: + return sceneAliased.ToHitmanSoundRecord(); + default: + return scene.ToHitmanSoundRecord(); + } +} + +void Hitman4WHDRecord::FromHitmanSoundRecord(const HitmanSoundRecord &soundRecord) +{ + switch (streams.id) + { + case 0x004F4850: + return streams.FromHitmanSoundRecord(soundRecord); + case 0: + return sceneAliased.FromHitmanSoundRecord(soundRecord); + default: + return scene.FromHitmanSoundRecord(soundRecord); + } +} + +bool Hitman4STRFile::Clear(const bool retVal) +{ + header = {}; + path.clear(); + + return retVal; +} + +bool Hitman4STRFile::Load(Hitman4Dialog& archiveDialog, const std::vector &wavData, const OrderedMap &whdRecordsMap) +{ + Clear(); + + if (wavData.empty()) + return Clear(false); + + if (wavData.size() < sizeof(Hitman4STRHeader)) + return Clear(false); + + std::memcpy(&header, wavData.data(), sizeof(Hitman4STRHeader)); + + if (wavData.size() - header.offsetToEntryTable < header.entriesCount * sizeof(Hitman4STRRecord)) + return Clear(false); + + recordTable.resize(header.entriesCount); + std::memcpy(recordTable.data(), wavData.data() + header.offsetToEntryTable, header.entriesCount * sizeof(Hitman4STRRecord)); + + wavDataTable.resize(header.entriesCount); + lipDataTable.resize(header.entriesCount); + wavHeaderTableData.resize(header.entriesCount); + stringTable.resize(header.entriesCount); + + wavHeaderTableBeginOffset = header.offsetToEntryTable; + stringTableBeginOffset = header.offsetToEntryTable; + + OrderedMap> wavDataOffsets; + + //OrderedSet missingWHDRecord; + + for (uint32_t i = 0; i < header.entriesCount; ++i) + { + const auto& strRecord = recordTable[i]; + + const auto [offsetsIt, ignored] = wavDataOffsets.try_emplace(strRecord.dataOffset, std::vector{}); + offsetsIt->second.emplace_back(i); + + if (wavData.size() - strRecord.headerOffset < strRecord.sizeOfHeader) + return Clear(false); + + if (wavData.size() - strRecord.fileNameOffset < strRecord.fileNameLength + 1) + return Clear(false); + + wavHeaderTableBeginOffset = std::min(wavHeaderTableBeginOffset, strRecord.headerOffset); + stringTableBeginOffset = std::min(stringTableBeginOffset, strRecord.fileNameOffset); + } + + if (wavDataOffsets.empty()) + return Clear(false); + + const auto [offsetsEndIt, emplaced] = wavDataOffsets.try_emplace(wavHeaderTableBeginOffset, std::vector{}); + if (!emplaced) + return Clear(false); + + offsetsEndIt->second.emplace_back(header.entriesCount); + + for (uint32_t i = 0; i < header.entriesCount; ++i) + { + const auto& strRecord = recordTable[i]; + + auto& strWAVHeader = wavHeaderTableData[i]; + strWAVHeader.resize(strRecord.sizeOfHeader); + std::memcpy(strWAVHeader.data(), wavData.data() + strRecord.headerOffset, strRecord.sizeOfHeader); + + auto& strFilename = stringTable[i]; + strFilename.resize(strRecord.fileNameLength); + std::memcpy(strFilename.data(), wavData.data() + strRecord.fileNameOffset, strRecord.fileNameLength); + + if (!fileNameToIndex.try_emplace(strFilename, i).second) + return Clear(false); + + if (!whdRecordsMap.contains(String8CI("Streams\\") += strFilename)) + { + // TODO - add entrie into map when they are not present and they point to "valid" data + //const auto& archiveFile = archiveDialog.GetFile(String8CI("Streams\\") += strFilename); + //[[maybe_unused]] const auto [fileMapIt, fileMapEmplaced] = archiveDialog.fileMap.try_emplace(archiveFile.path, HitmanFile{archiveFile.path, whdRecord->ToHitmanSoundRecord()}); + //assert(fileMapEmplaced); + // + //if (!missingWHDRecord.insert(i).second) + // return Clear(false); + + assert(wavDataOffsets.find(strRecord.dataOffset) != wavDataOffsets.end()); + assert(++wavDataOffsets.find(strRecord.dataOffset) != wavDataOffsets.end()); + + auto& wavDataSet = wavDataOffsets.find(strRecord.dataOffset)->second; + const auto wavDataEndOffset = (++wavDataOffsets.find(strRecord.dataOffset))->first; + const auto wavDataSize = wavDataEndOffset - strRecord.dataOffset; + + assert(wavData.size() >= wavDataEndOffset); + assert(wavDataSize % 0x0100 == 0); + + auto& strWAVData = wavDataTable[i]; + + const auto hasLIP = std::memcmp(wavData.data() + strRecord.dataOffset, "LIP ", sizeof(uint32_t)) == 0; + + auto strWAVDataOffset = wavDataSet.size() > 1 || hasLIP ? wavDataSize : 0; + if (strWAVDataOffset != 0) + { + if (wavDataSet.size() > 1) + { + for (auto wavDataSetItemIt = wavDataSet.begin(); wavDataSetItemIt != wavDataSet.end(); ++wavDataSetItemIt) + { + if (*wavDataSetItemIt == i) + { + wavDataSet.erase(wavDataSetItemIt); + break; + } + } + } + + for (const auto recordIndex : wavDataSet | std::views::reverse) + { + const auto& setRecord = recordTable[recordIndex]; + assert(strWAVDataOffset >= setRecord.dataSize); + strWAVDataOffset -= setRecord.dataSize; + strWAVDataOffset &= ~0xFFull; + } + } + + strWAVData.resize(strRecord.dataSize); + std::memcpy(strWAVData.data(), wavData.data() + strRecord.dataOffset + strWAVDataOffset, strRecord.dataSize); + + OptionalReference> lipDataOptRef; + if (hasLIP) + { + strWAVDataOffset = wavDataSize; + for (const auto recordIndex : wavDataSet | std::views::reverse) + { + const auto& setRecord = recordTable[recordIndex]; + assert(strWAVDataOffset >= setRecord.dataSize); + strWAVDataOffset -= setRecord.dataSize; + strWAVDataOffset &= ~0xFFull; + } + + assert(std::memcmp(wavData.data() + strRecord.dataOffset, "LIP ", sizeof(uint32_t)) == 0); + + auto& lipData = lipDataTable[i]; + lipData.resize(strWAVDataOffset); + std::memcpy(lipData.data(), wavData.data() + strRecord.dataOffset, strWAVDataOffset); + lipDataOptRef = lipData; + } + + recordMap.try_emplace(static_cast(strRecord.dataOffset), Hitman4WAVRecord{strWAVData, static_cast(strRecord.dataOffset), lipDataOptRef}); + } + } + + if (wavDataOffsets.empty()) + return Clear(false); + + recordMap.clear(); + + for (auto& [whdRecordPath, whdRecord] : whdRecordsMap) + { + if (whdRecord->streams.dataInStreams == 0) + continue; + + const auto fileIt = archiveDialog.fileMap.find(whdRecordPath); + if (fileIt == archiveDialog.fileMap.end()) + return Clear(false); + + auto& file = fileIt->second; + + const auto strRecordIndexIt = fileNameToIndex.find(whdRecordPath.native().substr(8)); + if (strRecordIndexIt == fileNameToIndex.end()) + return Clear(false); + + auto& strRecord = recordTable[strRecordIndexIt->second]; + + assert(wavDataOffsets.contains(strRecord.dataOffset)); + assert(++wavDataOffsets.find(strRecord.dataOffset) != wavDataOffsets.end()); + + const auto& wavDataSet = wavDataOffsets.find(strRecord.dataOffset)->second; + const auto wavDataEndOffset = (++wavDataOffsets.find(strRecord.dataOffset))->first; + const auto wavDataSize = wavDataEndOffset - strRecord.dataOffset; + + assert(wavData.size() >= wavDataEndOffset); + assert(wavDataSize % 0x0100 == 0); + + auto& strWAVHeader = wavHeaderTableData[strRecordIndexIt->second]; + const auto* strWAVHeaderCasted = reinterpret_cast(strWAVHeader.data()); + assert(strWAVHeaderCasted->unk4 == whdRecord->streams.dataSize || strRecord.dataSize == whdRecord->streams.dataSize || strRecord.unk24 == whdRecord->streams.dataSize); + + const auto hasLIP = std::memcmp(wavData.data() + strRecord.dataOffset, "LIP ", sizeof(uint32_t)) == 0; + + auto strWAVDataOffset = whdRecord->streams.id == 0 || hasLIP ? wavDataSize : 0; + if (strWAVDataOffset != 0) + { + assert(hasLIP || wavDataSet.size() == 2); + for (const auto recordIndex : wavDataSet | std::views::reverse) + { + const auto& setRecord = recordTable[recordIndex]; + assert(strWAVDataOffset >= setRecord.dataSize); + strWAVDataOffset -= setRecord.dataSize; + strWAVDataOffset &= ~0xFFull; + + if (recordIndex == strRecordIndexIt->second) + break; + } + } + + assert(hasLIP || strWAVDataOffset == (strWAVDataOffset & (~0xFFull))); + + file.data.resize(whdRecord->streams.dataSize); + std::memcpy(file.data.data(), wavData.data() + strRecord.dataOffset + strWAVDataOffset, whdRecord->streams.dataSize); + + OptionalReference> lipDataOptRef; + if (hasLIP) + { + strWAVDataOffset = wavDataSize; + for (const auto recordIndex : wavDataSet | std::views::reverse) + { + const auto& setRecord = recordTable[recordIndex]; + assert(strWAVDataOffset >= setRecord.dataSize); + strWAVDataOffset -= setRecord.dataSize; + strWAVDataOffset &= ~0xFFull; + } + + assert(std::memcmp(wavData.data() + strRecord.dataOffset, "LIP ", sizeof(uint32_t)) == 0); + + auto& lipData = lipDataTable[strRecordIndexIt->second]; + lipData.resize(strWAVDataOffset); + std::memcpy(lipData.data(), wavData.data() + strRecord.dataOffset, strWAVDataOffset); + lipDataOptRef = lipData; + } + + assert((whdRecord->streams.dataInStreams & 0xFF00) == 0 || ((whdRecord->streams.dataInStreams & 0xFF00) == 0x8200 || (whdRecord->streams.dataInStreams & 0xFF00) == 0x0100 && whdRecord->streams.formatTag == 0x01)); + + recordMap.try_emplace(whdRecord->streams.dataOffset, Hitman4WAVRecord{file.data, whdRecord->streams.dataOffset, lipDataOptRef}); + + const auto updatedArchiveRecord = SoundDataSoundRecord(file.archiveRecord, {file.data.data(), whdRecord->streams.dataSize}); + + if (updatedArchiveRecord.dataXXH3 == 0) + { + assert(hasLIP); + return Clear(false); + } + + file.archiveRecord = updatedArchiveRecord; + } + + if (recordMap.empty()) + return Clear(false); + + return true; +} + +bool Hitman4STRFile::Load(Hitman4Dialog& archiveDialog, const StringView8CI &loadPath, const OrderedMap &whdRecordsMap) +{ + if (!Load(archiveDialog, ReadWholeBinaryFile(loadPath), whdRecordsMap)) + return false; + + path = loadPath; + return true; +} + +bool Hitman4STRFile::Save(const StringView8CI &savePath) +{ + assert(false); + return false; +} + + +bool Hitman4WAVFile::Clear(const bool retVal) +{ + header = nullptr; + recordMap.clear(); + extraData.clear(); + path.clear(); + + return retVal; +} + +bool Hitman4WAVFile::Load(const std::vector &wavData, const OrderedMap &whdRecordsMap, OrderedMap& fileMap) +{ + Clear(); + + if (wavData.empty()) + return Clear(false); + + struct WAVFileData + { + Hitman4WHDRecord *record = nullptr; + HitmanFile& file; + }; + + auto resampledOffset = static_cast(wavData.size()); + size_t foundItems = 0; + OrderedMap resampledMap; + OrderedMap offsetToWAVFileDataMap; + for (auto& [whdRecordPath, whdRecord] : whdRecordsMap) + { + if (whdRecord->streams.dataInStreams != 0) + continue; + + auto offsetToWAVFileDataIt = offsetToWAVFileDataMap.find(whdRecord->streams.dataOffset); + if (offsetToWAVFileDataIt != offsetToWAVFileDataMap.end()) + { + resampledMap[resampledOffset] = whdRecord->streams.dataOffset; + whdRecord->streams.dataOffset = resampledOffset; + resampledOffset += whdRecord->streams.dataSize; + } + + offsetToWAVFileDataMap.insert({whdRecord->streams.dataOffset, {whdRecord, fileMap.at(whdRecordPath)}}); + + ++foundItems; + } + + if (offsetToWAVFileDataMap.size() != foundItems) + return Clear(false); + + recordMap.clear(); + + if (offsetToWAVFileDataMap.empty()) + { + auto& newData = extraData.emplace_back(); + newData.resize(wavData.size(), 0); + newData.shrink_to_fit(); + + std::memcpy(newData.data(), wavData.data(), wavData.size()); + recordMap.try_emplace(0, Hitman4WAVRecord{newData, 0}); + if (!recordMap.empty()) + header = reinterpret_cast(recordMap.at(0).data.data()); + else + header = nullptr; + + return true; + } + + uint32_t currOffset = 0; + for (auto& [offset, wavFileData] : offsetToWAVFileDataMap) + { + if (currOffset < offset) + { + auto& newData = extraData.emplace_back(); + newData.resize(offset - currOffset, 0); + newData.shrink_to_fit(); + + std::memcpy(newData.data(), wavData.data() + currOffset, offset - currOffset); + recordMap.try_emplace(currOffset, Hitman4WAVRecord{newData, currOffset, std::nullopt}); + } + assert(currOffset <= offset); + + auto& newData = wavFileData.file.data; + newData.resize(wavFileData.record->streams.dataSize, 0); + newData.shrink_to_fit(); + + auto trueOffset = offset >= wavData.size() ? resampledMap[offset] : offset; + if (std::memcmp(wavData.data() + trueOffset, "LIP ", sizeof(uint32_t)) == 0) + return false; + + std::memcpy(newData.data(), wavData.data() + trueOffset, wavFileData.record->streams.dataSize); + currOffset = offset + wavFileData.record->streams.dataSize; + recordMap.try_emplace(offset, Hitman4WAVRecord{newData, offset}); + + wavFileData.file.archiveRecord = SoundDataSoundRecord(wavFileData.file.archiveRecord, wavFileData.file.data); + + if (wavFileData.file.archiveRecord.dataXXH3 == 0) + return Clear(false); + } + + if (currOffset < wavData.size()) + { + auto& newData = extraData.emplace_back(); + newData.resize(wavData.size() - currOffset, 0); + newData.shrink_to_fit(); + + std::memcpy(newData.data(), wavData.data() + currOffset, wavData.size() - currOffset); + recordMap.try_emplace(currOffset, Hitman4WAVRecord{newData, currOffset}); + } + + header = reinterpret_cast(recordMap.at(0).data.data()); + + return true; +} + +bool Hitman4WAVFile::Load(const StringView8CI &loadPath, const OrderedMap &whdRecordsMap, OrderedMap& fileMap) +{ + if (!Load(ReadWholeBinaryFile(loadPath), whdRecordsMap, fileMap)) + return false; + + path = loadPath; + return true; +} + +bool Hitman4WAVFile::Save(const StringView8CI &savePathView) +{ + const auto savePath = savePathView.path(); + create_directories(savePath.parent_path()); + + const auto oldSync = std::ios_base::sync_with_stdio(false); + + std::ofstream wavData(savePath, std::ios::binary | std::ios::trunc); + + uint32_t offset = 0; + for (auto &record : recordMap | std::views::values) + { + record.newOffset = offset; + offset += static_cast(record.data.size()); + } + + for (auto &record : recordMap | std::views::values) + wavData.write(record.data.data(), record.data.size()); + + std::ios_base::sync_with_stdio(oldSync); + + path = savePath; + + return true; +} + +bool Hitman4WHDFile::Clear(const bool retVal) +{ + header = nullptr; + recordMap.clear(); + data.clear(); + path.clear(); + + return retVal; +} + +bool Hitman4WHDFile::Load(Hitman4Dialog& archiveDialog, const StringView8CI &loadPathView) +{ + if (data.empty()) + data = ReadWholeBinaryFile(loadPathView); + + if (data.empty()) + return Clear(false); + + recordMap.clear(); + + auto *whdPtr = data.data(); + header = reinterpret_cast(whdPtr); + whdPtr += sizeof(Hitman4WHDHeader); + + while (*whdPtr) + { + whdPtr += std::strlen(whdPtr) + 1; // + 0-15 bytes, so it is aligned on 16 bytes... + if (reinterpret_cast(whdPtr) % 16 != 0) + whdPtr += 16 - (reinterpret_cast(whdPtr) % 16); + while (memcmp(whdPtr, terminateBytes.data(), terminateBytes.size() * sizeof(uint32_t)) == 0) + whdPtr += 16; + + uint32_t iterCount = 0; + do { + auto *whdRecord = reinterpret_cast(whdPtr); + whdPtr += sizeof(Hitman4WHDRecord); + + bool nullBytesCheckPassed = true; + for (const auto nullByte : whdRecord->scene.nullBytes) + nullBytesCheckPassed &= nullByte == 0; + if (!nullBytesCheckPassed && whdRecord->streams.id != 0x004F4850) + { + if (whdRecord->sceneAliased.nullByte != 0) + { + whdPtr = reinterpret_cast(whdRecord); + break; + } + whdPtr -= 3 * sizeof(uint32_t); + } + + String8CI filePath(std::string_view(data.data() + whdRecord->scene.filePathOffset)); + auto filePathNative = filePath.path(); + + if (filePathNative.extension() != StringViewWCI(L".wav")) + return Clear(false); + + if (whdRecord->streams.dataInStreams == 0) + filePath = relative(loadPathView.path(), archiveDialog.basePath.path()) / filePath.path(); + else if (!filePath.native().starts_with("Streams")) + filePath = L"Streams" / filePathNative; + + auto& file = archiveDialog.GetFile(filePath); + + if (!recordMap.try_emplace(file.path, whdRecord).second) + return Clear(false); + + archiveDialog.whdRecordsMap[file.path].emplace_back(whdRecord); + [[maybe_unused]] const auto [fileMapIt, fileMapEmplaced] = archiveDialog.fileMap.try_emplace(file.path, HitmanFile{file.path, whdRecord->ToHitmanSoundRecord()}); + assert(whdRecord->streams.dataInStreams || fileMapEmplaced); + + ++iterCount; + } while (!reinterpret_cast(whdPtr)[0] && reinterpret_cast(whdPtr)[1] && std::distance(whdPtr, &data.back() + 1) != 16); + + if (iterCount > 1) + whdPtr += 2 * sizeof(uint32_t); + } + + path = loadPathView; + + return true; +} + +bool Hitman4WHDFile::Save(const Hitman4STRFile &streamsWAV, const Hitman4WAVFile &missionWAV, const StringView8CI &savePathView) +{ + for (auto *whdRecord : recordMap | std::views::values) + { + //const auto &wavRecordMap = whdRecord->streams.dataInStreams == 0 ? missionWAV.recordMap : streamsWAV.recordMap; + assert(whdRecord->streams.dataInStreams == 0); + const auto &wavRecordMap = missionWAV.recordMap; + const auto wavRecordIt = wavRecordMap.find(whdRecord->streams.dataOffset); + assert(wavRecordIt != wavRecordMap.end()); + if (wavRecordIt != wavRecordMap.end()) + whdRecord->streams.dataOffset = wavRecordIt->second.newOffset; + } + + const auto oldSync = std::ios_base::sync_with_stdio(false); + + std::ofstream whdData(savePathView.path(), std::ios::binary | std::ios::trunc); + whdData.write(data.data(), data.size()); + whdData.close(); + + std::ios_base::sync_with_stdio(oldSync); + + path = savePathView; + + return true; +} + +bool Hitman4Dialog::Clear(const bool retVal) +{ + whdFiles.clear(); + wavFiles.clear(); + streamsWAV.Clear(); + basePath.clear(); + fileMap.clear(); + whdRecordsMap.clear(); + + return HitmanDialog::Clear(retVal); +} + +bool Hitman4Dialog::ExportSingle(const StringView8CI &exportFolderPath, const StringView8CI &exportFilePath, + const Options &options) const +{ + if (!HitmanDialog::ExportSingle(exportFolderPath, exportFilePath, options)) + return false; + + if (!options.hitman4.exportWithLIPData) + return true; + + const auto streamsFileNameIt = std::ranges::find_if(streamsWAV.stringTable, [fileName = exportFilePath.native().substr(8)](const auto& elem){ return fileName == elem; }); + if (streamsFileNameIt == streamsWAV.stringTable.end()) + return true; + + const auto streamsIndex = std::distance(streamsWAV.stringTable.begin(), streamsFileNameIt); + + const auto& lipData = streamsWAV.lipDataTable[streamsIndex]; + if (lipData.empty()) + return true; + + const auto exportPath = (exportFolderPath.path() / exportFilePath.path()).replace_extension(L".LIP"); + + create_directories(exportPath.parent_path()); + + const auto oldSync = std::ios_base::sync_with_stdio(false); + + std::ofstream exportBin(exportPath, std::ios::binary | std::ios::trunc); + exportBin.write(lipData.data(), static_cast(lipData.size())); + + std::ios_base::sync_with_stdio(oldSync); + + return true; +} + +bool Hitman4Dialog::ImportSingle(const StringView8CI &importFolderPath, const StringView8CI &importFilePath, const Options &options) +{ + auto filePath = relative(importFilePath.path(), importFolderPath.path()); + auto fileIt = fileMap.find(filePath); + auto whdRecordsIt = whdRecordsMap.find(filePath); + if (fileIt == fileMap.end() || whdRecordsIt == whdRecordsMap.end()) + { + filePath.replace_extension(filePath.extension() == StringViewWCI(L".wav") ? L".ogg" : L".wav"); + fileIt = fileMap.find(filePath); + whdRecordsIt = whdRecordsMap.find(filePath); + if (fileIt == fileMap.end() || whdRecordsIt == whdRecordsMap.end()) + { + DisplayWarning(g_LocalizationManager.LocalizeFormat("HITMAN_DIALOG_WARNING_MISSING_FILE", importFilePath), + g_LocalizationManager.Localize("MESSAGEBOX_WARNING_GENERIC_TITLE"), false, options); + return false; + } + } + + if (!ImportSingleHitmanFile(fileIt->second, importFilePath, options)) + return false; + + for (auto* whdRecord : whdRecordsIt->second) + whdRecord->FromHitmanSoundRecord(fileIt->second.archiveRecord); + + return true; +} + +bool Hitman4Dialog::LoadImpl(const StringView8CI &loadPath, const Options &options) +{ + Clear(); + + const auto rootPath = loadPath.path().parent_path(); + const auto scenesPath = rootPath / L"Scenes"; + if (!exists(scenesPath)) + { + DisplayError(g_LocalizationManager.Localize("HITMAN_23_DIALOG_ERROR_MISSING_SCENES")); + return false; + } + + const auto allWHDFiles = GetAllFilesInDirectory(String8CI(scenesPath), ".whd", true); + + whdFiles.reserve(allWHDFiles.size()); + wavFiles.reserve(allWHDFiles.size()); + + basePath = rootPath; + + OrderedMap allWHDRecords; + for (const auto &whdPath : allWHDFiles) + { + auto &whdFile = whdFiles.emplace_back(); + if (!whdFile.Load(*this, whdPath)) + return Clear(false); + + for (const auto& [filePath, whdRecord] : whdFile.recordMap) + { + [[maybe_unused]] const auto res = allWHDRecords.try_emplace(filePath, whdRecord); + + // TODO - do we want to handle this in some way? duplicates pointing to streams should not be an issue unless offsets are different... + assert(res.second || (res.first->second->scene.dataInStreams && res.first->second->scene.dataInStreams == whdRecord->scene.dataInStreams && res.first->second->scene.dataOffset == whdRecord->scene.dataOffset)); + } + + if (!wavFiles.emplace_back().Load(String8CI(whdFile.path.path().replace_extension(L".wav")), whdFile.recordMap, fileMap)) + return Clear(false); + } + + const auto streamsWAVData = ReadWholeBinaryFile(loadPath); + if (!streamsWAV.Load(*this, streamsWAVData, allWHDRecords)) + return Clear(false); + + auto dataPath = GetProgramPath().path(); + if (dataPath.empty()) + return Clear(false); + + dataPath /= L"data"; + dataPath /= L"records"; + dataPath /= L"h4_"; + + originalDataPathPrefix = dataPath; + originalDataID = XXH3_64bits(streamsWAVData.data(), streamsWAVData.size()); + originalDataParentID = 0; + + if (!LoadOriginalData(options)) + return Clear(false); + + return true; +} + +bool Hitman4Dialog::SaveImpl(const StringView8CI &savePathView, const Options &options) +{ + const auto newBasePath = savePathView.path().parent_path(); + + streamsWAV.Save(savePathView); + + for (size_t i = 0; i < whdFiles.size(); ++i) + { + wavFiles[i].Save(String8CI(newBasePath / relative(wavFiles[i].path.path(), basePath.path()))); + whdFiles[i].Save(streamsWAV, wavFiles[i], String8CI(newBasePath / relative(whdFiles[i].path.path(), basePath.path()))); + } + + basePath = newBasePath; + + CleanDirty(); + + originalDataParentID = originalDataID; + + const auto streamsWAVData = ReadWholeBinaryFile(savePathView); + originalDataID = XXH3_64bits(streamsWAVData.data(), streamsWAVData.size()); + + if (!LoadOriginalData(options)) + return Clear(false); + + return true; +} + +int32_t Hitman4Dialog::DrawDialog() +{ + return DrawHitmanDialog(); +} + +bool Hitman4Dialog::IsSaveAllowed() const +{ + return G1AT_DEBUG_BUILD == 1; +} + +bool Hitman4Dialog::IsExportAllowed() const +{ + return true; +} + +bool Hitman4Dialog::IsImportAllowed() const +{ + return G1AT_DEBUG_BUILD == 1; +} + +const std::vector>& Hitman4Dialog::GetOpenFilter() +{ + static std::vector> filters; + if (!filters.empty()) + return filters; + + filters.emplace_back("FILE_DIALOG_FILTER_HITMAN4_STREAMS", "pc_*.str"); + + return filters; +} + +const std::vector>& Hitman4Dialog::GetSaveFilter() const +{ + static std::vector> filters; + if (!filters.empty()) + return filters; + + filters.emplace_back("FILE_DIALOG_FILTER_HITMAN4_STREAMS", "pc_*.str"); + + return filters; +} diff --git a/src/G1AT/Hitman4Dialog.hpp b/src/G1AT/Hitman4Dialog.hpp new file mode 100644 index 0000000..5b17dd0 --- /dev/null +++ b/src/G1AT/Hitman4Dialog.hpp @@ -0,0 +1,259 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 +// + +#pragma once + +#include "HitmanDialog.hpp" + +class Hitman4Dialog; + +struct Hitman4WHDHeader +{ + uint32_t fileSizeWithoutHeader = 0; + uint32_t fileSizeWithHeader = 0; + uint32_t unk8 = 3; // always 3 + uint32_t unkC = 4; // always 4 +}; + +inline constexpr std::array terminateBytes{0, 0, 0, 0}; + +union Hitman4WHDRecord +{ + struct Hitman4WHDRecordScene { + uint32_t filePathLength; + uint32_t filePathOffset; + uint16_t formatTag; // 1 - PCM 16-bit, 17 - IMA ADPCM, 4096 - OGG + uint16_t dataInStreams; // always 0 + uint32_t sampleRate; + uint32_t bitsPerSample; // 0 for OGG + uint32_t dataSizeUncompressed; + uint32_t dataSize; + uint32_t channels; + uint32_t dataOffset; + uint32_t samplesCount; + uint32_t blockAlign; // something weird for OGG! + uint32_t samplesPerBlock; // 0xCDCDCDCD for PCMs, 2041 for ADPCM, 0x004F3E93 for OGG... + uint32_t nullBytes[4]; + + HitmanSoundRecord ToHitmanSoundRecord() const; + void FromHitmanSoundRecord(const HitmanSoundRecord& soundRecord); + } scene; + + struct Hitman4WHDRecordSceneAliased + { + uint32_t nullByte; // always 0 + uint32_t filePathOffset; + uint16_t formatTag; // 1 - PCM 16-bit, 17 - IMA ADPCM, 4096 - OGG + uint16_t dataInStreams; // either 0 when in scene data or 128 when in streams (if 128. filePathLength must be equal "PHO\0") + uint32_t sampleRate; + uint32_t bitsPerSample; // 0 for OGG + uint32_t dataSizeUncompressed; + uint32_t dataSize; + uint32_t channels; + uint32_t dataOffset; // may start with "LIP " (0x2050494C) chunk, ignore 0x1000 bytes + uint32_t samplesCount; + uint32_t blockAlign; // something weird for OGG! + uint32_t fmtExtra; // 0xCDCDCDCD for PCMs, 2041 for ADPCM, 0x004F3E93 for OGG... + uint32_t nullBytes[4]; + + HitmanSoundRecord ToHitmanSoundRecord() const; + void FromHitmanSoundRecord(const HitmanSoundRecord& soundRecord); + } sceneAliased; + + struct Hitman4WHDRecordStreams + { + uint32_t id; // always "PHO\0" (0x004F4850) + uint32_t filePathOffset; + uint16_t formatTag; // 1 - PCM 16-bit, 17 - IMA ADPCM, 4096 - OGG + uint16_t dataInStreams; // either 0 when in scene data or 128 when in streams (if 128. filePathLength must be equal "PHO\0") + uint32_t unkC; // weird values in case filePathLength is "PHO\0" and dataInStreams is 128 + uint32_t bitsPerSample; // 0 for OGG + uint32_t dataSizeUncompressed; + uint32_t dataSize; + uint32_t channels; + uint32_t dataOffset; // may start with "LIP " (0x2050494C) chunk, ignore 0x1000 bytes + uint32_t samplesCount; + uint32_t unk18; + uint32_t fmtExtra; // 0xCDCDCDCD for PCMs, 2041 for ADPCM, 0x004F3E93 for OGG... + uint32_t unk2C; + uint32_t nullBytes[3]; + + HitmanSoundRecord ToHitmanSoundRecord() const; + void FromHitmanSoundRecord(const HitmanSoundRecord& soundRecord); + } streams; + + static_assert(sizeof(scene) == sizeof(sceneAliased)); + static_assert(sizeof(sceneAliased) == sizeof(streams)); + + HitmanSoundRecord ToHitmanSoundRecord() const; + void FromHitmanSoundRecord(const HitmanSoundRecord& soundRecord); +}; + +union Hitman4WAVHeader +{ + uint32_t unk0; // always 0 + uint32_t fileSizeWithHeader; + uint32_t unk8; // always 3 + uint32_t unkC; // always 4 +}; + +struct Hitman4LIPData +{ + uint32_t id; // compares to first 4 chars from "LIP " + uint32_t unk4; + uint32_t unk8; + uint32_t unkC; // one of three values - 0x00, 0x4063, 0x660000 -- also observed 0x408F, which also source was checking... it is used in german version + // some other data, at least 0x1000 in size +}; + +struct Hitman4STRHeader +{ + char id[0x0C] = {'I', 'O', 'I', 'S', 'N', 'D', 'S', 'T', 'R', 'E', 'A', 'M'}; + uint32_t version = 9; // always 0x09 + uint32_t offsetToEntryTable = 0; // points at the STR_Footer, right after string table ends + uint32_t entriesCount = 0; // same as number of STR_Data entries in STR_Footer + uint32_t dataBeginOffset = 0x0100; // offset to begining of data (or whole header size...) + uint32_t unk1C = 0; // was 0x0 in samples + uint32_t unk20 = 1; // was 0x1 in all samples + uint32_t unkLanguageId = 1; // was 0x1 in english samples and 0x2 in german, maybe some language id? + uint32_t unk28[0x100 - 0x28] = {}; +}; + +struct Hitman4STRRecordHeader1 +{ + uint32_t magic; // always 0x04 + uint32_t unk4; // possibly data size + uint32_t channels; // number of channels + uint32_t sampleRate; // sample rate + uint32_t bitsPerSample; // bits per sample +}; + +struct Hitman4STRRecordHeader2 : Hitman4STRRecordHeader1 +{ + // magic == 0x02 || 0x11 + uint32_t unk; // was 2 +}; + +struct Hitman4STRRecordHeader3 : Hitman4STRRecordHeader1 +{ + // magic == 0x03 + uint32_t blockAlign; // block alignment + uint32_t samplesPerBlock; // samples per block +}; + +struct Hitman4STRRecord +{ + uint64_t unk0; // some number, maybe id? doesnt seem to be too out of hand... + uint64_t dataOffset; // offset to beginning of data + uint64_t dataSize; // unknown number + uint64_t headerOffset; // offset to some table which seems to contain headers + uint32_t sizeOfHeader; // size of header + uint32_t unk24; // unknown number, doesnt seem to be an offset, maybe some size? + uint64_t fileNameLength; // length of filename in string table + uint64_t fileNameOffset; // offset to filename in string table + uint32_t unk38; // was 0x4 in sample where LIP data was present, 0x0 in other + uint32_t unk3C; // was 0x30 in sample where LIP data was present, 0x0 in other + uint64_t unk40; // is not 0 always but in quite a few places was +}; + +struct Hitman4WAVRecord +{ + std::vector& data; + uint32_t newOffset = 0; + OptionalReference> lipData = std::nullopt; +}; + +struct Hitman4STRFile +{ + bool Clear(bool retVal = false); + + bool Load(Hitman4Dialog& archiveDialog, const std::vector &wavData, const OrderedMap &whdRecordsMap); + bool Load(Hitman4Dialog& archiveDialog, const StringView8CI &loadPath, const OrderedMap &whdRecordsMap); + + bool Save(const StringView8CI &savePath); + + OrderedMap recordMap; + std::list> extraData; + + Hitman4STRHeader header; + std::vector> wavDataTable; + std::vector> lipDataTable; + std::vector> wavHeaderTableData; + std::vector stringTable; + std::vector recordTable; + + OrderedMap fileNameToIndex; + + //uint64_t wavDataTableBeginOffset = 0; // == header.dataBeginOffset + uint64_t wavHeaderTableBeginOffset = 0; + uint64_t stringTableBeginOffset = 0; + //uint64_t recordTableBeginOffset = 0; // == header.offsetToEntryTable + + String8CI path; +}; + +struct Hitman4WAVFile +{ + bool Clear(bool retVal = false); + + bool Load(const std::vector &wavData, const OrderedMap &whdRecordsMap, + OrderedMap& fileMap); + bool Load(const StringView8CI &loadPath, const OrderedMap &whdRecordsMap, + OrderedMap& fileMap); + + bool Save(const StringView8CI &savePath); + + Hitman4WAVHeader *header = nullptr; + OrderedMap recordMap; + std::list> extraData; + String8CI path; +}; + +struct Hitman4WHDFile +{ + bool Clear(bool retVal = false); + + bool Load(Hitman4Dialog& archiveDialog, const StringView8CI &loadPathView); + + bool Save(const Hitman4STRFile &streamsWAV, const Hitman4WAVFile &missionWAV, const StringView8CI &savePath); + + Hitman4WHDHeader *header = nullptr; + OrderedMap recordMap; + std::vector data; + String8CI path; +}; + +class Hitman4Dialog final : public HitmanDialog +{ +public: + bool Clear(bool retVal = false) override; + + bool ExportSingle(const StringView8CI &exportFolderPath, const StringView8CI &exportFilePath, const Options &options) const override; + + bool ImportSingle(const StringView8CI &importFolderPath, const StringView8CI &importFilePath, const Options &options) override; + + bool LoadImpl(const StringView8CI &loadPath, const Options &options) override; + + bool SaveImpl(const StringView8CI &savePath, const Options &options) override; + + int32_t DrawDialog() override; + + bool IsSaveAllowed() const override; + bool IsExportAllowed() const override; + bool IsImportAllowed() const override; + + static const std::vector>& GetOpenFilter(); + + const std::vector>& GetSaveFilter() const override; + + std::vector whdFiles; + std::vector wavFiles; + Hitman4STRFile streamsWAV; + + OrderedMap> whdRecordsMap; + + String8CI basePath; +}; diff --git a/src/G1AT/HitmanDialog.cpp b/src/G1AT/HitmanDialog.cpp new file mode 100644 index 0000000..1f93ffc --- /dev/null +++ b/src/G1AT/HitmanDialog.cpp @@ -0,0 +1,563 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 +// + +#include + +#include "HitmanDialog.hpp" + +#include "Utils.hpp" + +// TODO - use spans like in PCMS16 which are resized to max. required capacity before use and optimize a bit calling of this that way +// or even better, try to upgrade to std::ranges or views +bool HitmanFile::Import(SoundRecord soundRecord, const std::span &soundDataView, const Options &options) +{ + if (!soundRecord.dataSize || soundDataView.size() < soundRecord.dataSize) + return false; + + if (options.common.directImport) + return ImportNative(soundRecord, soundDataView, true, options); + + std::vector pcms16Decoded; + if (!PCMS16FromSoundData(soundRecord, soundDataView, pcms16Decoded, PCMS16_CONVERSION_FLAG_RAW_OUTPUT)) + return false; + + soundRecord.dataXXH3 = XXH3_64bits(pcms16Decoded.data(), pcms16Decoded.size() * sizeof(int16_t)); + + if (!options.common.importSameFiles && (archiveRecord.dataXXH3 == soundRecord.dataXXH3)) + return true; + + bool fixedData = false; + auto fixedHeader = PCMS16Header(soundRecord); + + if (options.common.fixChannels) + { + const auto result = PCMS16ChangeChannelCount(fixedHeader, pcms16Decoded, originalRecord.channels); + if (result < 0) + return false; + + fixedData |= result > 0; + } + + if (options.common.fixSampleRate) + { + const auto result = PCMS16ChangeSampleRate(fixedHeader, pcms16Decoded, originalRecord.sampleRate); + if (result < 0) + return false; + + fixedData |= result > 0; + } + + if (!options.common.transcodeToOriginalFormat || originalRecord.formatTag == 0x01) + { + archiveRecord = PCMS16SoundRecord(fixedHeader, pcms16Decoded); + archiveRecord.samplesPerBlock = 1; + + data.resize(archiveRecord.dataSize); + std::memcpy(data.data(), pcms16Decoded.data(), archiveRecord.dataSize); + + return true; + } + + if (fixedData || soundRecord.formatTag != originalRecord.formatTag) + { + switch (originalRecord.formatTag) + { + case 0x11: { + std::vector adpcmData(archiveRecord.dataSize); + if (!PCMS16ToADPCM(fixedHeader, pcms16Decoded, adpcmData, PCMS16_CONVERSION_FLAG_RAW_OUTPUT)) + return false; + + archiveRecord = ADPCMSoundRecord(ADPCMHeader(PCMS16SoundRecord(fixedHeader)), adpcmData); + + data.resize(archiveRecord.dataSize); + std::memcpy(data.data(), adpcmData.data(), archiveRecord.dataSize); + + return true; + } + case 0x1000: { + std::vector vorbisData; + if (!PCMS16ToVorbis(fixedHeader, pcms16Decoded, vorbisData)) + return false; + + archiveRecord = VorbisSoundRecord(VorbisHeader(vorbisData), vorbisData); + + data.resize(archiveRecord.dataSize); + std::memcpy(data.data(), vorbisData.data(), archiveRecord.dataSize); + + return true; + } + default: { + // Never should get here! + assert(false); + return false; + } + } + } + + return ImportNative(soundRecord, soundDataView, {}, options); +} + +bool HitmanFile::Import(const std::span &in, const Options &options) +{ + if (options.common.directImport) + return ImportNative(in, true, options); + + const auto soundRecord = SoundDataHeader(in); + return Import(soundRecord, SoundDataDataView(soundRecord, in), options); +} + +bool HitmanFile::Import(const StringView8CI &importPath, const Options& options) +{ + auto importData = ReadWholeBinaryFile(importPath); + if (importData.empty()) + return false; + + return Import(importData, options); +} + +bool HitmanFile::ImportNative(const SoundRecord &soundRecord, const std::span &soundDataView, const std::span &pcms16DataView, const Options &options) +{ + if (!soundRecord.dataSize || soundDataView.size() < soundRecord.dataSize) + return false; + + if (!options.common.importSameFiles && (archiveRecord.dataXXH3 == soundRecord.dataXXH3)) + return true; + + switch (soundRecord.formatTag) + { + case 0x01: + case 0x11: + case 0x1000: { + archiveRecord = soundRecord; + + if (archiveRecord.formatTag != 0x11) + archiveRecord.samplesPerBlock = 1; + + data.resize(archiveRecord.dataSize); + std::memcpy(data.data(), soundDataView.data(), archiveRecord.dataSize); + + return true; + } + case 0x8000: { + if (pcms16DataView.empty()) + return false; + + archiveRecord = PCMS16SoundRecord(PCMS16Header(soundRecord), soundRecord.dataXXH3); + archiveRecord.samplesPerBlock = 1; + + const auto newDataSize = pcms16DataView.size() * sizeof(int16_t); + data.resize(newDataSize); + std::memcpy(data.data(), pcms16DataView.data(), newDataSize); + + return true; + } + default: { + return false; + } + } +} + +bool HitmanFile::ImportNative(SoundRecord soundRecord, const std::span& soundDataView, const bool allowConversions, const Options& options) +{ + if (!soundRecord.dataSize || soundDataView.size() < soundRecord.dataSize) + return false; + + if (soundRecord.formatTag == 0x01) + { + soundRecord.dataXXH3 = XXH3_64bits(soundDataView.data(), soundRecord.dataSize); + return ImportNative(soundRecord, soundDataView, std::span{}, options); + } + + std::vector pcms16Decoded; + if (!PCMS16FromSoundData(soundRecord, soundDataView, pcms16Decoded, PCMS16_CONVERSION_FLAG_RAW_OUTPUT)) + return false; + + soundRecord.dataXXH3 = XXH3_64bits(pcms16Decoded.data(), pcms16Decoded.size() * sizeof(int16_t)); + std::span pcms16Span; + if (allowConversions) + pcms16Span = pcms16Decoded; + + return ImportNative(soundRecord, soundDataView, pcms16Span, options); +} + +bool HitmanFile::ImportNative(const std::span& in, const bool allowConversions, const Options& options) +{ + const auto soundRecord = SoundDataHeader(in); + return ImportNative(soundRecord, SoundDataDataView(soundRecord, in), allowConversions, options); +} + +bool HitmanFile::ImportNative(const StringView8CI &importPath, const bool allowConversions, const Options& options) +{ + auto importData = ReadWholeBinaryFile(importPath); + if (importData.empty()) + return false; + + return ImportNative(importData, allowConversions, options); +} + +bool HitmanFile::ExportNative(std::vector &outputBytes, const Options&) const +{ + const auto outIndexInput = outputBytes.size(); + + if (archiveRecord.formatTag == 0x01) + { + const auto header = PCMS16Header(archiveRecord); + outputBytes.resize(outIndexInput + sizeof(PCMS16_Header)); + std::memcpy(outputBytes.data() + outIndexInput, &header, sizeof(PCMS16_Header)); + } + else if (archiveRecord.formatTag == 0x11) + { + const auto header = ADPCMHeader(archiveRecord); + outputBytes.resize(outIndexInput + sizeof(ADPCM_Header)); + std::memcpy(outputBytes.data() + outIndexInput, &header, sizeof(ADPCM_Header)); + } + else if (archiveRecord.formatTag == 0x1000) + { + // NOTE: nothing to do, OGG files are completely contained in data + } + else + { + DisplayError(g_LocalizationManager.Localize("HITMAN_DIALOG_ERROR_UNKNOWN_FORMAT_IN_ARCHIVE")); + return false; + } + + const auto dataOffset = outputBytes.size(); + outputBytes.resize(dataOffset + data.size(), 0); + std::memcpy(outputBytes.data() + dataOffset, data.data(), data.size()); + + return true; +} + +bool HitmanFile::Export(std::vector &outputBytes, const Options& options) const +{ + if (!options.common.transcodeToPlayableFormat) + return ExportNative(outputBytes, options); + + assert(archiveRecord.channels >= 1); + assert(archiveRecord.channels <= 2); + if (archiveRecord.channels < 1 || archiveRecord.channels > 2) + { + assert(false); + return false; + } + + assert(archiveRecord.sampleRate >= 8000); + assert(archiveRecord.sampleRate <= 48000); + if (archiveRecord.sampleRate < 8000 || archiveRecord.sampleRate > 48000) + { + assert(false); + return false; + } + + OrderedSet normalSampleRates{0, 11025, 22050, 44100, 48000}; + auto normalSampleRateIt = std::ranges::lower_bound(normalSampleRates, archiveRecord.sampleRate); + if (normalSampleRateIt == normalSampleRates.end()) + { + assert(false); + return false; + } + if (++normalSampleRateIt == normalSampleRates.end()) + { + assert(false); + return false; + } + + const auto normalSampleRate = *normalSampleRateIt; + if (normalSampleRate == archiveRecord.sampleRate) + { + if (archiveRecord.formatTag == 0x01) + return ExportNative(outputBytes, options); + + if (!options.common.transcodeOGGToPCM && archiveRecord.formatTag == 0x1000) + return ExportNative(outputBytes, options); + } + + auto pcms16Header = PCMS16Header(archiveRecord); + std::vector pcms16Decoded; + if (!PCMS16FromSoundData(archiveRecord, data, pcms16Decoded, PCMS16_CONVERSION_FLAG_RAW_OUTPUT)) + { + assert(false); + return false; + } + + if (PCMS16ChangeSampleRate(pcms16Header, pcms16Decoded, normalSampleRate) < 0) + { + assert(false); + return false; + } + + const auto outIndexInput = outputBytes.size(); + outputBytes.resize(outIndexInput + sizeof(PCMS16_Header) + pcms16Decoded.size() * sizeof(int16_t)); + std::memcpy(outputBytes.data() + outIndexInput, &pcms16Header, sizeof(PCMS16_Header)); + std::memcpy(outputBytes.data() + outIndexInput + sizeof(PCMS16_Header), pcms16Decoded.data(), pcms16Decoded.size() * sizeof(int16_t)); + + return true; +} + +bool HitmanDialog::Clear(const bool retVal) +{ + opened = false; + fileMap.clear(); + + return ArchiveDialog::Clear(retVal); +} + +bool HitmanDialog::IsSaveAllowed() const +{ + return true; +} + +bool HitmanDialog::IsExportAllowed() const +{ + return true; +} + +bool HitmanDialog::IsImportAllowed() const +{ + return true; +} + +bool HitmanDialog::GenerateOriginalData(const Options &options) +{ + auto dataPathString = originalDataPathPrefix; + dataPathString += std::format("{:16X}", originalDataID); + const auto dataPath = dataPathString.path(); + create_directories(dataPath.parent_path()); + + const auto oldSync = std::ios_base::sync_with_stdio(false); + + std::ofstream genFile(dataPath, std::ios::binary | std::ios::trunc); + + genFile.write(reinterpret_cast(&originalDataParentID), sizeof(uint64_t)); + + if (originalDataParentID) + { + std::ios_base::sync_with_stdio(oldSync); + + const auto thisDataID = originalDataID; + originalDataID = originalDataParentID; + const auto loadResult = LoadOriginalData(options); + originalDataID = thisDataID; + + return loadResult; + } + + const uint64_t entriesCount = fileMap.size(); + genFile.write(reinterpret_cast(&entriesCount), sizeof(uint64_t)); + + for (auto &[filePath, file] : fileMap) + { + assert(file.archiveRecord.dataXXH3 != 0); + file.originalRecord = file.archiveRecord; + + auto &archiveFile = GetFile(filePath); + archiveFile.original = true; + + genFile.write(reinterpret_cast(&file.originalRecord), sizeof(HitmanSoundRecord)); + } + + std::ios_base::sync_with_stdio(oldSync); + + return true; +} + +bool HitmanDialog::LoadOriginalData(const Options &options) +{ + auto dataPathString = originalDataPathPrefix; + dataPathString += std::format("{:16X}", originalDataID); + const auto dataPath = dataPathString.path(); + if (!exists(dataPath)) + { + if (originalDataID != originalDataParentID) + return GenerateOriginalData(options); + + DisplayError(g_LocalizationManager.Localize("HITMAN_DIALOG_ERROR_CORRUPTED_ORIGINAL_RECORDS_CACHE")); + ReloadOriginalData(true, options); + return true; + } + + const auto oldSync = std::ios_base::sync_with_stdio(false); + + std::ifstream genFile(dataPath, std::ios::binary); + + uint64_t parentID = 0; + genFile.read(reinterpret_cast(&parentID), sizeof(uint64_t)); + + if (parentID != 0) + { + std::ios_base::sync_with_stdio(oldSync); + + originalDataParentID = parentID; + + const auto thisDataID = originalDataID; + originalDataID = originalDataParentID; + const auto loadResult = LoadOriginalData(options); + originalDataID = thisDataID; + + return loadResult; + } + + uint64_t entriesCount = 0; + genFile.read(reinterpret_cast(&entriesCount), sizeof(uint64_t)); + + if (entriesCount != fileMap.size()) + return false; + + for (auto &[filePath, file] : fileMap) + { + genFile.read(reinterpret_cast(&file.originalRecord), sizeof(HitmanSoundRecord)); + + assert(file.originalRecord.dataXXH3 != 0); + assert(file.archiveRecord.dataXXH3 != 0); + + auto &archiveFile = GetFile(filePath); + archiveFile.original = file.originalRecord == file.archiveRecord; + } + + std::ios_base::sync_with_stdio(oldSync); + + return true; +} + +bool HitmanDialog::ImportSingleHitmanFile(HitmanFile &hitmanFile, std::vector &data, const bool allowConversions, const Options &options) +{ + if (allowConversions) + { + if (!hitmanFile.Import(data, options)) + return false; + } + else + { + if (!hitmanFile.ImportNative(data, false, options)) + return false; + } + + auto &archiveFile = GetFile(hitmanFile.path); + + if (hitmanFile.originalRecord.dataXXH3 == 0) + hitmanFile.originalRecord = hitmanFile.archiveRecord; + + archiveFile.original = hitmanFile.originalRecord == hitmanFile.archiveRecord; + archiveFile.dirty = archiveFile.dirty || !archiveFile.original; + + return true; +} + +bool HitmanDialog::ImportSingleHitmanFile(HitmanFile &hitmanFile, const StringView8CI &importFilePath, const Options &options) +{ + auto inputData = ReadWholeBinaryFile(importFilePath); + return ImportSingleHitmanFile(hitmanFile, inputData, !options.common.directImport, options); +} + +bool HitmanDialog::ExportSingleHitmanFile(const HitmanFile &hitmanFile, std::vector &data, bool doConversion, const Options &options) const +{ + if (doConversion) + return hitmanFile.Export(data, options); + + return hitmanFile.ExportNative(data, options); +} + +bool HitmanDialog::ExportSingleHitmanFile(const HitmanFile &hitmanFile, const StringView8CI &exportFolderPath, const Options &options) const +{ + std::vector outputData; + if (!ExportSingleHitmanFile(hitmanFile, outputData, options.common.transcodeToPlayableFormat, options)) + return false; + + if (outputData.size() < 4) + return false; + + auto exportPath = exportFolderPath.path() / hitmanFile.path.path(); + const auto magic = *reinterpret_cast(outputData.data()); + switch (magic) + { + case 'FFIR': { + exportPath.replace_extension(L".wav"); + break; + } + case 'SggO': { + exportPath.replace_extension(L".ogg"); + break; + } + default: { + return false; + } + } + + create_directories(exportPath.parent_path()); + + const auto oldSync = std::ios_base::sync_with_stdio(false); + + std::ofstream exportBin(exportPath, std::ios::binary | std::ios::trunc); + exportBin.write(outputData.data(), static_cast(outputData.size())); + + std::ios_base::sync_with_stdio(oldSync); + + return true; +} + +bool HitmanDialog::ExportSingle(const StringView8CI &exportFolderPath, const StringView8CI &exportFilePath, const Options &options) const +{ + const auto fileMapIt = fileMap.find(exportFilePath); + if (fileMapIt == fileMap.cend()) + return false; + + return ExportSingleHitmanFile(fileMapIt->second, exportFolderPath, options); +} + +int32_t HitmanDialog::ReloadOriginalData(const bool reset, const Options &options) +{ + needsOriginalDataReload = true; + needsOriginalDataReset |= reset; + + if (IsInProgress()) + return 2; + + if (originalDataID == 0) + { + needsOriginalDataReload = false; + return needsOriginalDataReset ? 2 : 0; + } + + if (needsOriginalDataReset) + { + auto dataPathString = originalDataPathPrefix; + dataPathString += std::format("{:16X}", originalDataID); + + [[maybe_unused]] std::error_code errorCode; + std::filesystem::remove(dataPathString.path(), errorCode); + + needsOriginalDataReset = false; + } + + needsOriginalDataReload &= fileMap.empty(); + + if (!needsOriginalDataReload) + return 1; + + progressMessage = g_LocalizationManager.Localize("HITMAN_DIALOG_LOADING_ORIGINAL_RECORDS"); + progressNext = 0; + progressNextTotal = 1; + + progressTask = std::async(std::launch::async, [this, options = Options::Get()] { + LoadOriginalData(options); + + std::unique_lock progressMessageLock(progressMessageMutex); + progressMessage.clear(); + progressNext = 1; + }); + + needsOriginalDataReload = false; + + return 1; +} + +int32_t HitmanDialog::DrawHitmanDialog() +{ + if (needsOriginalDataReload || needsOriginalDataReset) + ReloadOriginalData(); + + return DrawBaseDialog(); +} diff --git a/src/G1AT/HitmanDialog.hpp b/src/G1AT/HitmanDialog.hpp new file mode 100644 index 0000000..9d74e51 --- /dev/null +++ b/src/G1AT/HitmanDialog.hpp @@ -0,0 +1,63 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 +// + +#pragma once + +#include "ArchiveDialog.hpp" + +using HitmanSoundRecord = SoundRecord; + +struct HitmanFile +{ + bool Import(SoundRecord soundRecord, const std::span& soundDataView, const Options& options); + bool Import(const std::span& in, const Options& options); + bool Import(const StringView8CI &importPath, const Options& options); + + bool ImportNative(const SoundRecord & soundRecord, const std::span& soundDataView, const std::span& pcms16DataView, const Options& options); + bool ImportNative(SoundRecord soundRecord, const std::span& soundDataView, bool allowConversions, const Options& options); + bool ImportNative(const std::span& in, bool allowConversions, const Options& options); + bool ImportNative(const StringView8CI &importPath, bool allowConversions, const Options& options); + + bool Export(std::vector &outputBytes, const Options& options) const; + + bool ExportNative(std::vector &outputBytes, const Options& options) const; + + StringView8CI path; + HitmanSoundRecord archiveRecord; + HitmanSoundRecord originalRecord; + std::vector data; +}; + +class HitmanDialog : public ArchiveDialog +{ +public: + bool Clear(bool retVal = false) override; + + bool IsSaveAllowed() const override; + bool IsExportAllowed() const override; + bool IsImportAllowed() const override; + + bool GenerateOriginalData(const Options &options = Options::Get()); + bool LoadOriginalData(const Options &options = Options::Get()); + int32_t ReloadOriginalData(bool reset = false, const Options &options = Options::Get()); + + bool ImportSingleHitmanFile(HitmanFile &hitmanFile, std::vector &data, bool allowConversions, const Options &options); + bool ImportSingleHitmanFile(HitmanFile &hitmanFile, const StringView8CI &importFilePath, const Options &options); + + bool ExportSingleHitmanFile(const HitmanFile &hitmanFile, std::vector &data, bool doConversion, const Options &options) const; + bool ExportSingleHitmanFile(const HitmanFile &hitmanFile, const StringView8CI &exportFolderPath, const Options &options) const; + + bool ExportSingle(const StringView8CI &exportFolderPath, const StringView8CI &exportFilePath, const Options &options) const override; + + int32_t DrawHitmanDialog(); + + OrderedMap fileMap; + String8CI originalDataPathPrefix; + uint64_t originalDataID = 0; + uint64_t originalDataParentID = 0; + bool needsOriginalDataReload = false; + bool needsOriginalDataReset = false; +}; diff --git a/src/G1AT/Options.cpp b/src/G1AT/Options.cpp new file mode 100644 index 0000000..0515b2e --- /dev/null +++ b/src/G1AT/Options.cpp @@ -0,0 +1,209 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 + +#include + +#include "Options.hpp" + +#include "Utils.hpp" + +void CommonSettings::Load(const toml::table &aInputRoot) +{ + ResetToDefaults(); + + const auto& commonTable = aInputRoot["common"]; + + disableWarnings = commonTable["disable_warnings"].value_or(disableWarnings); + importSameFiles = commonTable["import_original_files"].value_or(importSameFiles); + fixChannels = commonTable["fix_channels"].value_or(fixChannels); + fixSampleRate = commonTable["fix_sample_rate"].value_or(fixSampleRate); + transcodeToOriginalFormat = commonTable["transcode_to_original_format"].value_or(transcodeToOriginalFormat); + directImport = commonTable["direct_import"].value_or(directImport); + transcodeToPlayableFormat = commonTable["transcode_to_playable_format"].value_or(transcodeToPlayableFormat); + transcodeOGGToPCM = commonTable["transcode_ogg_to_pcm"].value_or(transcodeOGGToPCM); + + g_LocalizationManager.SetLanguage(commonTable["language"].value_or(g_LocalizationManager.GetLanguage().native())); +} + +void CommonSettings::Save(toml::table &aOutputRoot) const +{ + toml::table commonTable; + + commonTable.emplace("disable_warnings", disableWarnings); + commonTable.emplace("import_original_files", importSameFiles); + commonTable.emplace("fix_channels", fixChannels); + commonTable.emplace("fix_sample_rate", fixSampleRate); + commonTable.emplace("transcode_to_original_format", transcodeToOriginalFormat); + commonTable.emplace("direct_import", directImport); + commonTable.emplace("transcode_to_playable_format", transcodeToPlayableFormat); + commonTable.emplace("transcode_ogg_to_pcm", transcodeOGGToPCM); + + commonTable.emplace("language", g_LocalizationManager.GetLanguage().native()); + + aOutputRoot.emplace("common", std::move(commonTable)); +} + +void CommonSettings::ResetToDefaults() +{ + *this = {}; +} + +void CommonSettings::DrawDialog() +{ + if (!ImGui::BeginTabItem(g_LocalizationManager.Localize("SETTINGS_DIALOG_COMMON_GROUP").c_str())) + return; + + if (ImGui::BeginCombo(g_LocalizationManager.Localize("SETTINGS_DIALOG_LANGUAGE").c_str(), g_LocalizationManager.GetLanguage().c_str())) + { + const auto availableLanguages = g_LocalizationManager.GetAvailableLanguages(); + for (const auto& language : availableLanguages) + { + bool selected = g_LocalizationManager.GetLanguage() == language; + if (ImGui::Selectable(language.c_str(), &selected)) + g_LocalizationManager.SetLanguage(language); + } + ImGui::EndCombo(); + } + + ImGui::Checkbox(g_LocalizationManager.Localize("SETTINGS_DIALOG_DISABLE_WARNINGS").c_str(), &disableWarnings); + + ImGui::Checkbox(g_LocalizationManager.Localize("SETTINGS_DIALOG_IMPORT_ORIGINAL_FILES").c_str(), &importSameFiles); + + ImGui::Checkbox(g_LocalizationManager.Localize("SETTINGS_DIALOG_DIRECT_IMPORT").c_str(), + &directImport); + + if (directImport) + ImGui::BeginDisabled(); + + ImGui::TreePush(&directImport); + + fixChannels &= !directImport; + ImGui::Checkbox(g_LocalizationManager.Localize("SETTINGS_DIALOG_FIX_CHANNELS").c_str(), &fixChannels); + + fixSampleRate &= !directImport; + ImGui::Checkbox(g_LocalizationManager.Localize("SETTINGS_DIALOG_FIX_SAMPLE_RATE").c_str(), &fixSampleRate); + + transcodeToOriginalFormat &= !directImport; + ImGui::Checkbox(g_LocalizationManager.Localize("SETTINGS_DIALOG_TRANSCODE_TO_ORIGINAL_FORMAT").c_str(), &transcodeToOriginalFormat); + + ImGui::TreePop(); + + if (directImport) + ImGui::EndDisabled(); + + ImGui::Checkbox(g_LocalizationManager.Localize("SETTINGS_DIALOG_TRANSCODE_TO_PLAYABLE_FORMAT").c_str(), &transcodeToPlayableFormat); + + if (!transcodeToPlayableFormat) + ImGui::BeginDisabled(); + + ImGui::TreePush(&transcodeToPlayableFormat); + + transcodeOGGToPCM &= transcodeToPlayableFormat; + ImGui::Checkbox(g_LocalizationManager.Localize("SETTINGS_DIALOG_TRANSCODE_OGG_TO_PCM").c_str(), &transcodeOGGToPCM); + + if (!transcodeToPlayableFormat) + ImGui::EndDisabled(); + + ImGui::TreePop(); + + ImGui::EndTabItem(); +} + +void Hitman4Settings::Load(const toml::table &aInputRoot) +{ + ResetToDefaults(); + + const auto& hitman4Table = aInputRoot["hitman4"]; + + exportWithLIPData = hitman4Table["export_with_lip_data"].value_or(exportWithLIPData); +} + +void Hitman4Settings::Save(toml::table &aOutputRoot) const +{ + toml::table hitman4Table; + + hitman4Table.emplace("export_with_lip_data", exportWithLIPData); + + aOutputRoot.emplace("hitman4", std::move(hitman4Table)); +} + +void Hitman4Settings::ResetToDefaults() +{ + *this = {}; +} + +void Hitman4Settings::DrawDialog() +{ + if (!ImGui::BeginTabItem(g_LocalizationManager.Localize("SETTINGS_DIALOG_HITMAN4_GROUP").c_str())) + return; + + ImGui::Checkbox(g_LocalizationManager.Localize("SETTINGS_DIALOG_HITMAN4_EXPORT_WITH_LIP_DATA").c_str(), &exportWithLIPData); + + ImGui::EndTabItem(); +} + +void Options::Load() +{ + auto optionsPath = GetProgramPath().path(); + if (optionsPath.empty()) + return; + + optionsPath /= L"config.toml"; + + auto config = toml::parse_file(optionsPath.native()); + if (config.failed()) + return; + + common.Load(config); + hitman4.Load(config); +} + +void Options::Save() const +{ + auto optionsPath = GetProgramPath().path(); + if (optionsPath.empty()) + return; + + optionsPath /= L"config.toml"; + + toml::table config; + + common.Save(config); + hitman4.Save(config); + + std::ofstream(optionsPath, std::ios::trunc) << config; +} + +void Options::ResetToDefaults() +{ + common.ResetToDefaults(); + hitman4.ResetToDefaults(); + + Save(); +} + +void Options::DrawDialog() +{ + if (!opened) + return; + + if (!ImGui::Begin(g_LocalizationManager.Localize("SETTINGS_DIALOG_TITLE").c_str(), &opened)) + return; + + const auto beforeUpdate = *this; + + if (ImGui::BeginTabBar("##SettingCategoryTabs")) + { + common.DrawDialog(); + hitman4.DrawDialog(); + + ImGui::EndTabBar(); + } + + if (beforeUpdate != *this) + Save(); + + ImGui::End(); +} diff --git a/src/G1AT/Options.hpp b/src/G1AT/Options.hpp new file mode 100644 index 0000000..b36aa87 --- /dev/null +++ b/src/G1AT/Options.hpp @@ -0,0 +1,73 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 + +#pragma once + +#include "Singleton.hpp" + +class CommonSettings +{ +public: + void Load(const toml::table &aInputRoot); + void Save(toml::table &aOutputRoot) const; + void ResetToDefaults(); + + void DrawDialog(); + + [[nodiscard]] auto operator<=>(const CommonSettings &) const = default; + + bool disableWarnings{false}; + bool importSameFiles{false}; + bool fixChannels{true}; + bool fixSampleRate{true}; + bool transcodeToOriginalFormat{true}; + bool directImport{false}; + bool transcodeToPlayableFormat{true}; + bool transcodeOGGToPCM{false}; +}; + +class Hitman4Settings +{ +public: + void Load(const toml::table &aInputRoot); + void Save(toml::table &aOutputRoot) const; + void ResetToDefaults(); + + void DrawDialog(); + + [[nodiscard]] auto operator<=>(const Hitman4Settings &) const = default; + + bool exportWithLIPData{false}; +}; + +class Options : public Singleton +{ +public: + void Load(); + void Save() const; + void ResetToDefaults(); + + void DrawDialog(); + + [[nodiscard]] auto operator<=>(const Options &other) const + { + if (const auto cmp = common <=> other.common; cmp != std::strong_ordering::equal) + return cmp; + + if (const auto cmp = hitman4 <=> other.hitman4; cmp != std::strong_ordering::equal) + return cmp; + + return std::strong_ordering::equal; + } + + [[nodiscard]] bool operator==(const Options &other) const + { + return (*this <=> other) == std::strong_ordering::equal; + } + + CommonSettings common; + Hitman4Settings hitman4; + bool opened = false; +}; diff --git a/src/Singleton.hpp b/src/G1AT/Singleton.hpp similarity index 100% rename from src/Singleton.hpp rename to src/G1AT/Singleton.hpp diff --git a/src/Tests.cpp b/src/G1AT/Tests.cpp similarity index 96% rename from src/Tests.cpp rename to src/G1AT/Tests.cpp index 3093003..7d4e283 100644 --- a/src/Tests.cpp +++ b/src/G1AT/Tests.cpp @@ -4,7 +4,7 @@ // SPDX-License-Identifier: EUPL-1.2 // -#include "Precompiled.hpp" +#include #ifdef G1AT_BUILD_TESTS diff --git a/src/Utils.cpp b/src/G1AT/Utils.cpp similarity index 76% rename from src/Utils.cpp rename to src/G1AT/Utils.cpp index d17d121..bd85f6e 100644 --- a/src/Utils.cpp +++ b/src/G1AT/Utils.cpp @@ -4,7 +4,7 @@ // SPDX-License-Identifier: EUPL-1.2 // -#include "Precompiled.hpp" +#include #include "Utils.hpp" @@ -75,7 +75,7 @@ String8CI BrowseDirectoryDialog() return path; } -String8CI OpenFileDialog(const StringView8CI &filters, const StringView8CI &defaultFileName) +std::pair OpenFileDialog(const StringView8CI &filters, const StringView8CI &defaultFileName) { OPENFILENAMEA ofn; ZeroMemory(&ofn, sizeof(ofn)); @@ -94,41 +94,17 @@ String8CI OpenFileDialog(const StringView8CI &filters, const StringView8CI &defa ofn.Flags = OFN_LONGNAMES | OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; if (!GetOpenFileNameA(&ofn)) - return {}; + return {{}, 0}; fileName.resize(strlen(fileName.c_str())); - if (fileName.native().rfind('.') != String8CI::npos) - return fileName; - - const char* defaultExt = filters.empty() ? nullptr : filters.data() + strlen(filters.data()) + 1; - if (defaultExt && defaultExt[0] && defaultExt[0] != '.') - defaultExt = strchr(defaultExt, '.'); - - if (defaultExt && defaultExt[0] && defaultExt[1] != '*') - { - fileName += defaultExt; - if (!exists(fileName.path())) - fileName.clear(); - - return fileName; - } + if (fileName.native().rfind('.') == String8CI::npos) + return {{}, 0}; - const auto filePath = fileName.path(); - const auto allFilesInParent = GetAllFilesInDirectory(String8CI(filePath.parent_path()), "", false); - if (allFilesInParent.empty()) - return fileName; - - for (const auto& fileInParent : allFilesInParent) - { - if (fileInParent.native().find(fileName.native()) != String8CI::npos) - return fileInParent; - } - - return fileName; + return {fileName, ofn.nFilterIndex}; } -String8CI SaveFileDialog(const StringView8CI &filters, const StringView8CI &defaultFileName) +std::pair SaveFileDialog(const StringView8CI &filters, const StringView8CI &defaultFileName) { OPENFILENAMEA ofn; ZeroMemory(&ofn, sizeof(ofn)); @@ -151,17 +127,10 @@ String8CI SaveFileDialog(const StringView8CI &filters, const StringView8CI &defa fileName.resize(strlen(fileName.c_str())); - if (fileName.native().rfind('.') != String8CI::npos) - return fileName; - - const char* defaultExt = filters.empty() ? nullptr : filters.data() + strlen(filters.data()) + 1; - if (defaultExt && defaultExt[0] && defaultExt[0] != '.') - defaultExt = strchr(defaultExt, '.'); + if (fileName.native().rfind('.') == String8CI::npos) + return {{}, 0}; - if (defaultExt && defaultExt[0] && defaultExt[1] != '*') - return fileName += defaultExt; - - return fileName; + return {fileName, ofn.nFilterIndex}; } std::vector GetAllFilesInDirectory(const StringView8CI &directory, const StringView8CI &extension, bool recursive) @@ -249,13 +218,29 @@ std::vector GetPathStems(StringView8CI pathView) return pathStems; } -String8CI ChangeExtension(const StringView8CI &path, const StringView8CI &newExtension) +String8CI MakeFileDialogFilter(const std::vector> &filters) { - const auto pathExtPos = path.native().rfind('.'); - if (pathExtPos == StringView8CI::npos) - return String8CI(path) += newExtension; + if (filters.empty()) + return {}; + + String8CI allFilters; + for (const auto& filter : filters | std::views::values) + { + if (!allFilters.empty()) + allFilters += ";"; + + allFilters += filter; + } - String8CI newPath = path.native().substr(0, pathExtPos); - newPath += newExtension; - return newPath; + String8CI result; + + if (filters.size() > 1) + result = std::format("{0} ({1})?{1}?", g_LocalizationManager.Localize("FILE_DIALOG_FILTER_ALL_SUPPORTED"), allFilters); + + for (const auto& [identifier, filter] : filters) + result += std::format("{0} ({1})?{1}?", g_LocalizationManager.Localize(identifier), filter); + + std::ranges::replace(result, '?', '\0'); + + return result; } diff --git a/src/G1AT/Utils.hpp b/src/G1AT/Utils.hpp new file mode 100644 index 0000000..abaecaf --- /dev/null +++ b/src/G1AT/Utils.hpp @@ -0,0 +1,31 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 +// + +#pragma once + +std::vector ReadWholeBinaryFile(const StringView8CI &acpPath); + +String8 ReadWholeTextFile(const StringView8CI &acpPath); + +float GetAlignedItemWidth(int64_t acItemsCount); + +String8CI BrowseDirectoryDialog(); + +std::pair OpenFileDialog(const StringView8CI &filters, const StringView8CI &defaultFileName = ""); + +std::pair SaveFileDialog(const StringView8CI &filters, const StringView8CI &defaultFileName = ""); + +std::vector GetAllFilesInDirectory(const StringView8CI &directory, const StringView8CI &extension, bool recursive); + +StringView8CI GetProgramPath(); + +int32_t DisplayError(const StringView8 &message, const StringView8 &title = g_LocalizationManager.Localize("MESSAGEBOX_ERROR_GENERIC_TITLE"), bool yesNo = false); + +int32_t DisplayWarning(const StringView8 &message, const StringView8 &title = g_LocalizationManager.Localize("MESSAGEBOX_WARNING_GENERIC_TITLE"), bool yesNo = false, const Options &options = Options::Get()); + +std::vector GetPathStems(StringView8CI pathView); + +String8CI MakeFileDialogFilter(const std::vector>& filters); diff --git a/src/Hitman4Dialog.cpp b/src/Hitman4Dialog.cpp deleted file mode 100644 index e2a21b2..0000000 --- a/src/Hitman4Dialog.cpp +++ /dev/null @@ -1,551 +0,0 @@ -// -// Created by Andrej Redeky. -// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. -// SPDX-License-Identifier: EUPL-1.2 -// - -#include "Precompiled.hpp" - -#include "Hitman4Dialog.hpp" - -HitmanSoundRecord Hitman4WHDRecord::Hitman4WHDRecordMission::ToHitmanSoundRecord() const -{ - assert(filePathLength > 0 && filePathLength < 0x004F4850); - - const auto resBitsPerSample = static_cast(formatTag == 4096 ? 16 : bitsPerSample); - const auto resChannels = static_cast(channels); - const auto resBlockAlign = static_cast(formatTag == 4096 ? 2 * channels : blockAlign); - const auto resFmtExtra = static_cast(formatTag == 17 ? fmtExtra : 1); - - assert(resBlockAlign == 2 * channels || formatTag == 17); - assert(resBlockAlign != 1024 || formatTag == 17); - - return { - 0, - dataSizeUncompressed, - dataSize, - sampleRate, - formatTag, - resBitsPerSample, - resChannels, - resBlockAlign, - resFmtExtra - }; -} - -void Hitman4WHDRecord::Hitman4WHDRecordMission::FromHitmanSoundRecord(const HitmanSoundRecord &soundRecord) -{ - assert(formatTag != 4096 || formatTag == soundRecord.formatTag); - - formatTag = soundRecord.formatTag; - sampleRate = soundRecord.sampleRate; - bitsPerSample = formatTag == 4096 ? 0 : soundRecord.bitsPerSample; - dataSizeUncompressed = soundRecord.dataSizeUncompressed; - dataSize = soundRecord.dataSize; - channels = soundRecord.channels; - samplesCount = soundRecord.dataSizeUncompressed / sizeof(int16_t); - blockAlign = formatTag == 4096 ? blockAlign : soundRecord.blockAlign; - fmtExtra = formatTag == 4096 ? 0x004F3E93 : (formatTag == 1 ? 0xCDCDCDCD : soundRecord.fmtExtra); -} - -HitmanSoundRecord Hitman4WHDRecord::Hitman4WHDRecordConcatenated::ToHitmanSoundRecord() const -{ - assert(nullByte == 0); - - const auto resBitsPerSample = static_cast(formatTag == 4096 ? 16 : bitsPerSample); - const auto resChannels = static_cast(channels); - const auto resBlockAlign = static_cast(formatTag == 4096 ? 2 * channels : blockAlign); - const auto resFmtExtra = static_cast(formatTag == 17 ? fmtExtra : 1); - - assert(resBlockAlign == 2 * channels || formatTag == 17); - assert(resBlockAlign != 1024 || formatTag == 17); - - return { - 0, - dataSizeUncompressed, - dataSize, - sampleRate, - formatTag, - resBitsPerSample, - resChannels, - resBlockAlign, - resFmtExtra - }; -} - -void Hitman4WHDRecord::Hitman4WHDRecordConcatenated::FromHitmanSoundRecord(const HitmanSoundRecord &soundRecord) -{ - assert(formatTag != 4096 || formatTag == soundRecord.formatTag); - - formatTag = soundRecord.formatTag; - sampleRate = soundRecord.sampleRate; - bitsPerSample = formatTag == 4096 ? 0 : soundRecord.bitsPerSample; - dataSizeUncompressed = soundRecord.dataSizeUncompressed; - dataSize = soundRecord.dataSize; - channels = soundRecord.channels; - samplesCount = soundRecord.dataSizeUncompressed / sizeof(int16_t); - blockAlign = formatTag == 4096 ? blockAlign : soundRecord.blockAlign; - fmtExtra = formatTag == 4096 ? 0x004F3E93 : (formatTag == 1 ? 0xCDCDCDCD : soundRecord.fmtExtra); -} - -HitmanSoundRecord Hitman4WHDRecord::Hitman4WHDRecordStreams::ToHitmanSoundRecord() const -{ - assert(id == 0x004F4850); - - const auto resBitsPerSample = static_cast(formatTag == 4096 ? 16 : bitsPerSample); - const auto resChannels = static_cast(channels); - const auto resBlockAlign = static_cast(formatTag == 4096 || formatTag == 1 ? 2 * channels : 1024); - const auto resFmtExtra = static_cast(formatTag == 17 ? fmtExtra : 1); - - assert(resBlockAlign == 2 * channels || formatTag == 17); - assert(resBlockAlign != 1024 || formatTag == 17); - - return { - 0, - dataSizeUncompressed, - dataSize, - unkC, - formatTag, - resBitsPerSample, - resChannels, - resBlockAlign, - resFmtExtra - }; -} - -void Hitman4WHDRecord::Hitman4WHDRecordStreams::FromHitmanSoundRecord(const HitmanSoundRecord &soundRecord) -{ - assert(formatTag == soundRecord.formatTag); - - formatTag = soundRecord.formatTag; - unk2C = soundRecord.sampleRate; - bitsPerSample = formatTag == 4096 ? 0 : soundRecord.bitsPerSample; - dataSizeUncompressed = soundRecord.dataSizeUncompressed; - dataSize = soundRecord.dataSize; - channels = soundRecord.channels; - samplesCount = soundRecord.dataSizeUncompressed / sizeof(int16_t); - fmtExtra = formatTag == 4096 ? 0x004F3E93 : (formatTag == 1 ? 0xCDCDCDCD : soundRecord.fmtExtra); -} - -HitmanSoundRecord Hitman4WHDRecord::ToHitmanSoundRecord() const -{ - assert((streams.id == 0x004F4850) == (streams.dataInStreams == 128)); - - assert(streams.formatTag != 1 || streams.bitsPerSample == 16); - assert(streams.formatTag != 17 || streams.bitsPerSample == 4); - assert(streams.formatTag != 4096 || streams.bitsPerSample == 0); - - assert(mission.formatTag != 17 || mission.blockAlign == 1024); - - assert(streams.formatTag != 1 || streams.fmtExtra == 0xCDCDCDCD); - assert(streams.formatTag != 17 || streams.fmtExtra == 2041); - assert(streams.formatTag != 4096 || streams.fmtExtra == 0x004F3E93); - - assert(streams.unk2C == 0 || ((streams.formatTag == 17 || streams.formatTag == 1) && streams.id == 0x004F4850)); - - assert(streams.nullBytes[0] == 0); - assert(streams.nullBytes[1] == 0); - assert(streams.nullBytes[2] == 0); - - switch (streams.id) - { - case 0x004F4850: - return streams.ToHitmanSoundRecord(); - case 0: - return concatenated.ToHitmanSoundRecord(); - default: - return mission.ToHitmanSoundRecord(); - } -} - -void Hitman4WHDRecord::FromHitmanSoundRecord(const HitmanSoundRecord &soundRecord) -{ - switch (streams.id) - { - case 0x004F4850: - return streams.FromHitmanSoundRecord(soundRecord); - case 0: - return concatenated.FromHitmanSoundRecord(soundRecord); - default: - return mission.FromHitmanSoundRecord(soundRecord); - } -} - -bool Hitman4WAVFile::Clear(const bool retVal) -{ - header = nullptr; - recordMap.clear(); - lipsData.clear(); - extraData.clear(); - path.clear(); - - return retVal; -} - -bool Hitman4WAVFile::Load(const StringView8CI &loadPath, const OrderedMap &whdRecordsMap, OrderedMap& fileMap, const bool isMissionWAV) -{ - Clear(); - - const auto wavData = ReadWholeBinaryFile(loadPath); - if (wavData.empty()) - return Clear(false); - - struct WAVFileData - { - Hitman4WHDRecord *record = nullptr; - HitmanFile& file; - }; - - auto resampledOffset = static_cast(wavData.size()); - size_t foundItems = 0; - OrderedMap resampledMap; - OrderedMap offsetToWAVFileDataMap; - for (auto& [whdRecordPath, whdRecord] : whdRecordsMap) - { - if ((whdRecord->streams.dataInStreams == 0) != isMissionWAV) - continue; - - auto offsetToWAVFileDataIt = offsetToWAVFileDataMap.find(whdRecord->streams.dataOffset); - if (offsetToWAVFileDataIt != offsetToWAVFileDataMap.end()) - { - resampledMap[resampledOffset] = whdRecord->streams.dataOffset; - whdRecord->streams.dataOffset = resampledOffset; - resampledOffset += whdRecord->streams.dataSize; - } - - offsetToWAVFileDataMap.insert({whdRecord->streams.dataOffset, {whdRecord, fileMap.at(whdRecordPath)}}); - - ++foundItems; - } - - if (offsetToWAVFileDataMap.size() != foundItems) - return Clear(false); - - recordMap.clear(); - - if (offsetToWAVFileDataMap.empty()) - { - auto& newData = extraData.emplace_back(); - newData.resize(wavData.size(), 0); - newData.shrink_to_fit(); - - std::memcpy(newData.data(), wavData.data(), wavData.size()); - recordMap.try_emplace(0, Hitman4WAVRecord{newData, 0}); - if (isMissionWAV && !recordMap.empty()) - header = reinterpret_cast(recordMap.at(0).data.data()); - else - header = nullptr; - - path = loadPath; - - return true; - } - - uint32_t currOffset = 0; - for (auto& [offset, wavFileData] : offsetToWAVFileDataMap) - { - if (currOffset < offset) - { - auto& newData = extraData.emplace_back(); - newData.resize(offset - currOffset, 0); - newData.shrink_to_fit(); - - std::memcpy(newData.data(), wavData.data() + currOffset, offset - currOffset); - recordMap.try_emplace(currOffset, Hitman4WAVRecord{newData, currOffset, std::nullopt}); - } - assert(currOffset <= offset); - - auto& newData = wavFileData.file.data; - newData.resize(wavFileData.record->streams.dataSize, 0); - newData.shrink_to_fit(); - - auto trueOffset = offset >= wavData.size() ? resampledMap[offset] : offset; - const auto *wavDataLIP = reinterpret_cast(wavData.data() + trueOffset); - OptionalReference> lipData = std::nullopt; - if (memcmp(wavDataLIP, "LIP ", sizeof(uint32_t)) == 0) - { - auto& emplacedLipData = lipsData.emplace_back(); - - emplacedLipData.resize(0x1000, 0); - emplacedLipData.shrink_to_fit(); - std::memcpy(emplacedLipData.data(), wavData.data() + trueOffset, emplacedLipData.size()); - - lipData = emplacedLipData; - trueOffset += static_cast(emplacedLipData.size()); - } - std::memcpy(newData.data(), wavData.data() + trueOffset, wavFileData.record->streams.dataSize); - currOffset = offset + wavFileData.record->streams.dataSize + (lipData ? static_cast(lipData->get().size()) : 0u); - recordMap.try_emplace(offset, Hitman4WAVRecord{newData, offset, lipData}); - } - - if (currOffset < wavData.size()) - { - auto& newData = extraData.emplace_back(); - newData.resize(wavData.size() - currOffset, 0); - newData.shrink_to_fit(); - - std::memcpy(newData.data(), wavData.data() + currOffset, wavData.size() - currOffset); - recordMap.try_emplace(currOffset, Hitman4WAVRecord{newData, currOffset}); - } - - header = reinterpret_cast(recordMap.at(0).data.data()); - - path = loadPath; - - return true; -} - -bool Hitman4WAVFile::Save(const StringView8CI &savePathView) -{ - const auto savePath = savePathView.path(); - create_directories(savePath.parent_path()); - - const auto oldSync = std::ios_base::sync_with_stdio(false); - - std::ofstream wavData(savePath, std::ios::binary | std::ios::trunc); - - uint32_t offset = 0; - for (auto &record : recordMap | std::views::values) - { - record.newOffset = offset; - offset += static_cast(record.data.size()); - } - - for (auto &record : recordMap | std::views::values) - wavData.write(record.data.data(), record.data.size()); - - std::ios_base::sync_with_stdio(oldSync); - - path = savePath; - - return true; -} - -bool Hitman4WHDFile::Clear(const bool retVal) -{ - header = nullptr; - recordMap.clear(); - data.clear(); - path.clear(); - - return retVal; -} - -bool Hitman4WHDFile::Load(Hitman4Dialog& archiveDialog, const StringView8CI &loadPathView) -{ - if (data.empty()) - data = ReadWholeBinaryFile(loadPathView); - - if (data.empty()) - return Clear(false); - - recordMap.clear(); - - auto *whdPtr = data.data(); - header = reinterpret_cast(whdPtr); - whdPtr += sizeof(Hitman4WHDHeader); - - while (*whdPtr) - { - whdPtr += std::strlen(whdPtr) + 1; // + 0-15 bytes, so it is aligned on 16 bytes... - if (reinterpret_cast(whdPtr) % 16 != 0) - whdPtr += 16 - (reinterpret_cast(whdPtr) % 16); - while (memcmp(whdPtr, terminateBytes.data(), terminateBytes.size()) == 0) - whdPtr += 16; - - uint32_t iterCount = 0; - do { - auto *whdRecord = reinterpret_cast(whdPtr); - whdPtr += sizeof(Hitman4WHDRecord); - - bool nullBytesCheckPassed = true; - for (const auto nullByte : whdRecord->mission.nullBytes) - nullBytesCheckPassed &= nullByte == 0; - if (!nullBytesCheckPassed && whdRecord->streams.id != 0x004F4850) - { - if (whdRecord->concatenated.nullByte != 0) - { - whdPtr = reinterpret_cast(whdRecord); - break; - } - whdPtr -= 3 * sizeof(uint32_t); - } - - String8CI filePath(std::string_view(data.data() + whdRecord->mission.filePathOffset)); - auto filePathNative = filePath.path(); - - if (filePathNative.extension() != StringViewWCI(L".wav")) - return Clear(false); - - if (whdRecord->streams.dataInStreams == 0) - filePath = relative(loadPathView.path(), archiveDialog.basePath.path()) / filePath.path(); - else - filePath = L"Streams" / filePathNative; - - auto& file = archiveDialog.GetFile(filePath); - - if (!recordMap.try_emplace(file.path, whdRecord).second) - return Clear(false); - - archiveDialog.whdRecordsMap[file.path].emplace_back(whdRecord); - archiveDialog.fileMap[file.path].archiveRecord = whdRecord->ToHitmanSoundRecord(); - - ++iterCount; - } while (!reinterpret_cast(whdPtr)[0] && reinterpret_cast(whdPtr)[1] && std::distance(whdPtr, &data.back() + 1) != 16); - - if (iterCount > 1) - whdPtr += 2 * sizeof(uint32_t); - } - - path = loadPathView; - - return true; -} - -bool Hitman4WHDFile::Save(const Hitman4WAVFile &streamsWAV, const Hitman4WAVFile &missionWAV, const StringView8CI &savePathView) -{ - for (auto *whdRecord : recordMap | std::views::values) - { - const auto &wavRecordMap = whdRecord->streams.dataInStreams == 0 ? missionWAV.recordMap : streamsWAV.recordMap; - const auto wavRecordIt = wavRecordMap.find(whdRecord->streams.dataOffset); - assert(wavRecordIt != wavRecordMap.end()); - if (wavRecordIt != wavRecordMap.end()) - whdRecord->streams.dataOffset = wavRecordIt->second.newOffset; - } - - const auto oldSync = std::ios_base::sync_with_stdio(false); - - std::ofstream whdData(savePathView.path(), std::ios::binary | std::ios::trunc); - whdData.write(data.data(), data.size()); - whdData.close(); - - std::ios_base::sync_with_stdio(oldSync); - - path = savePathView; - - return true; -} - -bool Hitman4Dialog::Clear(const bool retVal) -{ - whdFiles.clear(); - wavFiles.clear(); - streamsWAV.Clear(); - basePath.clear(); - fileMap.clear(); - whdRecordsMap.clear(); - - return HitmanDialog::Clear(retVal); -} - -bool Hitman4Dialog::ImportSingle(const StringView8CI &importFolderPath, const StringView8CI &importFilePath, const Options &options) -{ - String8CI filePath = relative(importFilePath.path(), importFolderPath.path()); - auto fileIt = fileMap.find(filePath); - auto whdRecordsIt = whdRecordsMap.find(filePath); - if (fileIt == fileMap.end() || whdRecordsIt == whdRecordsMap.end()) - { - const StringView8CI nextExtension = filePath.path().extension() == StringViewWCI(L".wav") ? ".ogg" : ".wav"; - filePath = ChangeExtension(filePath, nextExtension); - fileIt = fileMap.find(filePath); - whdRecordsIt = whdRecordsMap.find(filePath); - if (fileIt == fileMap.end() || whdRecordsIt == whdRecordsMap.end()) - { - DisplayWarning(LocalizationManager::Get().LocalizeFormat("HITMAN_DIALOG_WARNING_MISSING_FILE", importFilePath), - LocalizationManager::Get().Localize("MESSAGEBOX_WARNING_GENERIC_TITLE"), false, options); - return false; - } - } - - if (!ImportSingleHitmanFile(fileIt->second, filePath, importFilePath, options)) - return false; - - for (auto* whdRecord : whdRecordsIt->second) - whdRecord->FromHitmanSoundRecord(fileIt->second.archiveRecord); - - return true; -} - -bool Hitman4Dialog::LoadImpl(const StringView8CI &loadPath, const Options &options) -{ - Clear(); - - const auto rootPath = loadPath.path().parent_path(); - const auto scenesPath = rootPath / L"Scenes"; - if (!exists(scenesPath)) - { - DisplayError(LocalizationManager::Get().Localize("HITMAN_23_DIALOG_ERROR_MISSING_SCENES")); - return false; - } - - const auto allWHDFiles = GetAllFilesInDirectory(String8CI(scenesPath), ".whd", true); - - whdFiles.reserve(allWHDFiles.size()); - wavFiles.reserve(allWHDFiles.size()); - - basePath = rootPath; - - OrderedMap allWHDRecords; - for (const auto &whdPath : allWHDFiles) - { - auto &whdFile = whdFiles.emplace_back(); - if (!whdFile.Load(*this, whdPath)) - return Clear(false); - - for (const auto& [filePath, whdRecord] : whdFile.recordMap) - { - [[maybe_unused]] const auto res = allWHDRecords.try_emplace(filePath, whdRecord); - - // TODO - do we want to handle this in some way? duplicates pointing to streams should not be an issue unless offsets are different... - assert(res.second || (res.first->second->mission.dataInStreams && res.first->second->mission.dataInStreams == whdRecord->mission.dataInStreams && res.first->second->mission.dataOffset == whdRecord->mission.dataOffset)); - } - - if (!wavFiles.emplace_back().Load(ChangeExtension(whdFile.path, ".wav"), whdFile.recordMap, fileMap, true)) - return Clear(false); - } - - if (!streamsWAV.Load(loadPath, allWHDRecords, fileMap, false)) - return Clear(false); - - if (!options.common.checkOriginality) - return true; - - auto dataPath = GetProgramPath().path(); - if (dataPath.empty()) - return Clear(false); - - dataPath /= L"data"; - dataPath /= L"records"; - dataPath /= L"h4"; - - originalDataPath = dataPath; - - if (!LoadOriginalData()) - return Clear(false); - - return true; -} - -bool Hitman4Dialog::SaveImpl(const StringView8CI &savePathView, const Options &options) -{ - const auto newBasePath = savePathView.path().parent_path(); - - streamsWAV.Save(savePathView); - - for (size_t i = 0; i < whdFiles.size(); ++i) - { - wavFiles[i].Save(String8CI(newBasePath / relative(wavFiles[i].path.path(), basePath.path()))); - whdFiles[i].Save(streamsWAV, wavFiles[i], String8CI(newBasePath / relative(whdFiles[i].path.path(), basePath.path()))); - } - - basePath = newBasePath; - - CleanDirty(); - - return true; -} - -void Hitman4Dialog::DrawDialog() -{ - DrawHitmanDialog("Blood Money", "Hitman 4 Streams (pc_eng.str)\0pc_eng.str\0", "pc_eng.str"); -} diff --git a/src/Hitman4Dialog.hpp b/src/Hitman4Dialog.hpp deleted file mode 100644 index ab309fb..0000000 --- a/src/Hitman4Dialog.hpp +++ /dev/null @@ -1,177 +0,0 @@ -// -// Created by Andrej Redeky. -// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. -// SPDX-License-Identifier: EUPL-1.2 -// - -#pragma once - -#include "HitmanDialog.hpp" - -class Hitman4Dialog; - -struct Hitman4WHDHeader -{ - uint32_t fileSizeWithoutHeader = 0; - uint32_t fileSizeWithHeader = 0; - uint32_t unk8 = 3; // always 3 - uint32_t unkC = 4; // always 4 -}; - -inline constexpr std::array terminateBytes{0, 0, 0, 0}; - -union Hitman4WHDRecord -{ - struct Hitman4WHDRecordMission { - uint32_t filePathLength; - uint32_t filePathOffset; - uint16_t formatTag; // 1 - PCM 16-bit, 17 - IMA ADPCM, 4096 - OGG - uint16_t dataInStreams; // always 0 - uint32_t sampleRate; - uint32_t bitsPerSample; // 0 for OGG - uint32_t dataSizeUncompressed; - uint32_t dataSize; - uint32_t channels; - uint32_t dataOffset; - uint32_t samplesCount; - uint32_t blockAlign; // something weird for OGG! - uint32_t fmtExtra; // 0xCDCDCDCD for PCMs, 2041 for ADPCM, 0x004F3E93 for OGG... - uint32_t nullBytes[4]; - - HitmanSoundRecord ToHitmanSoundRecord() const; - void FromHitmanSoundRecord(const HitmanSoundRecord& soundRecord); - } mission; - - struct Hitman4WHDRecordConcatenated - { - uint32_t nullByte; // always 0 - uint32_t filePathOffset; - uint16_t formatTag; // 1 - PCM 16-bit, 17 - IMA ADPCM, 4096 - OGG - uint16_t dataInStreams; // either 0 when in mission data or 128 when in streams (if 128. filePathLength must be equal "PHO\0") - uint32_t sampleRate; - uint32_t bitsPerSample; // 0 for OGG - uint32_t dataSizeUncompressed; - uint32_t dataSize; - uint32_t channels; - uint32_t dataOffset; // may start with "LIP " (0x2050494C) chunk, ignore 0x1000 bytes - uint32_t samplesCount; - uint32_t blockAlign; // something weird for OGG! - uint32_t fmtExtra; // 0xCDCDCDCD for PCMs, 2041 for ADPCM, 0x004F3E93 for OGG... - uint32_t nullBytes[4]; - - HitmanSoundRecord ToHitmanSoundRecord() const; - void FromHitmanSoundRecord(const HitmanSoundRecord& soundRecord); - } concatenated; - - struct Hitman4WHDRecordStreams - { - uint32_t id; // always "PHO\0" (0x004F4850) - uint32_t filePathOffset; - uint16_t formatTag; // 1 - PCM 16-bit, 17 - IMA ADPCM, 4096 - OGG - uint16_t dataInStreams; // either 0 when in mission data or 128 when in streams (if 128. filePathLength must be equal "PHO\0") - uint32_t unkC; // weird values in case filePathLength is "PHO\0" and dataInStreams is 128 - uint32_t bitsPerSample; // 0 for OGG - uint32_t dataSizeUncompressed; - uint32_t dataSize; - uint32_t channels; - uint32_t dataOffset; // may start with "LIP " (0x2050494C) chunk, ignore 0x1000 bytes - uint32_t samplesCount; - uint32_t unk18; - uint32_t fmtExtra; // 0xCDCDCDCD for PCMs, 2041 for ADPCM, 0x004F3E93 for OGG... - uint32_t unk2C; - uint32_t nullBytes[3]; - - HitmanSoundRecord ToHitmanSoundRecord() const; - void FromHitmanSoundRecord(const HitmanSoundRecord& soundRecord); - } streams; - - static_assert(sizeof(mission) == sizeof(concatenated)); - static_assert(sizeof(concatenated) == sizeof(streams)); - - HitmanSoundRecord ToHitmanSoundRecord() const; - void FromHitmanSoundRecord(const HitmanSoundRecord& soundRecord); -}; - -union Hitman4WAVHeader -{ - struct Hitman4WAVHeaderWHD { - uint32_t unk0; // always 0 - uint32_t fileSizeWithHeader; - uint32_t unk8; // always 3 - uint32_t unkC; // always 4 - } whd; - - struct Hitman4WAVHeaderStreams { - char id[0x10]; - uint32_t stringTableEndOffset; - uint32_t unk14[0x100 - 0x14]; - } streams; -}; - -struct Hitman4LIPData -{ - uint32_t id; // compares to first 4 chars from "LIP " - uint32_t unk4; - uint32_t unk8; - uint32_t unkB; - // dataSize array of bytes follows -}; - -struct Hitman4WAVRecord -{ - std::vector& data; - uint32_t newOffset = 0; - OptionalReference> lipData = std::nullopt; -}; - -struct Hitman4WAVFile -{ - bool Clear(bool retVal = false); - - bool Load(const StringView8CI &loadPath, const OrderedMap &whdRecordsMap, - OrderedMap& fileMap, bool isMissionWAV); - - bool Save(const StringView8CI &savePath); - - Hitman4WAVHeader *header = nullptr; - OrderedMap recordMap; - std::list> lipsData; - std::list> extraData; - String8CI path; -}; - -struct Hitman4WHDFile -{ - bool Clear(bool retVal = false); - - bool Load(Hitman4Dialog& archiveDialog, const StringView8CI &loadPathView); - - bool Save(const Hitman4WAVFile &streamsWAV, const Hitman4WAVFile &missionWAV, const StringView8CI &savePath); - - Hitman4WHDHeader *header = nullptr; - OrderedMap recordMap; - std::vector data; - String8CI path; -}; - -class Hitman4Dialog final : public HitmanDialog, public Singleton -{ -public: - bool Clear(bool retVal = false) override; - - bool ImportSingle(const StringView8CI &importFolderPath, const StringView8CI &importFilePath, const Options &options) override; - - bool LoadImpl(const StringView8CI &loadPath, const Options &options) override; - - bool SaveImpl(const StringView8CI &savePath, const Options &options) override; - - void DrawDialog() override; - - std::vector whdFiles; - std::vector wavFiles; - Hitman4WAVFile streamsWAV; - - OrderedMap> whdRecordsMap; - - String8CI basePath; -}; diff --git a/src/HitmanDialog.cpp b/src/HitmanDialog.cpp deleted file mode 100644 index 151924c..0000000 --- a/src/HitmanDialog.cpp +++ /dev/null @@ -1,614 +0,0 @@ -// -// Created by Andrej Redeky. -// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. -// SPDX-License-Identifier: EUPL-1.2 -// -// TODO - original records data is heavily dependent on archive contents currently! make it do some more proper caching of data. -// - also make sure that dialogs shared between multiple games do not check bytes of files directly (contents different == bytes different) -// - current record data corresponds to Steam versions, they do not match for GOG (reason for this to be brought up) -// - -#include "Precompiled.hpp" - -#include "HitmanDialog.hpp" - -bool HitmanFile::Import(char inputBytes[], const size_t inputBytesCount, const Options& options) -{ - SF_VIRTUAL_DATA_FIXED virtSndData{inputBytes, static_cast(inputBytesCount)}; - SndfileHandle sndFile(g_VirtSndFileIOFixed, &virtSndData); - if (!sndFile) - { - DisplayWarning(LocalizationManager::Get().Localize("HITMAN_DIALOG_WARNING_IMPORT_LOADING_DATA"), - LocalizationManager::Get().Localize("MESSAGEBOX_WARNING_GENERIC_TITLE"), false, options); - return false; - } - - auto frames = static_cast(sndFile.frames()); - if (frames == 0) - { - DisplayWarning(LocalizationManager::Get().Localize("HITMAN_DIALOG_WARNING_IMPORT_DECODING_DATA"), - LocalizationManager::Get().Localize("MESSAGEBOX_WARNING_GENERIC_TITLE"), false, options); - return false; - } - - auto channels = static_cast(sndFile.channels()); - uint32_t dataSizeUncompressed = frames * channels * sizeof(int16_t); - uint32_t sampleRate = sndFile.samplerate(); - - thread_local static std::vector sndFileData; - sndFileData.resize(dataSizeUncompressed, 0); - if (sndFile.readf(reinterpret_cast(sndFileData.data()), frames) != frames) - { - DisplayWarning(LocalizationManager::Get().Localize("HITMAN_DIALOG_WARNING_IMPORT_DECODING_DATA"), - LocalizationManager::Get().Localize("MESSAGEBOX_WARNING_GENERIC_TITLE"), false, options); - return false; - } - - sf_close(sndFile.takeOwnership()); - - if (options.common.checkOriginality) - archiveRecord.dataXXH3 = XXH3_64bits(sndFileData.data(), dataSizeUncompressed); - - if (!options.common.importOriginalFiles && (originalRecord.dataXXH3 == archiveRecord.dataXXH3)) - return true; - - auto castedDataSize = sndFileData.size() / sizeof(int16_t); - auto* castedData = reinterpret_cast(sndFileData.data()); - - if (options.common.fixChannels) - { - if (originalRecord.channels < channels) - { - assert(channels == 2); - assert(originalRecord.channels == 1); - - for (size_t i = 0; i < castedDataSize / 2; ++i) - castedData[i] = static_cast((static_cast(castedData[i * 2]) + - static_cast(castedData[i * 2 + 1])) / 2); - - channels = 1; - dataSizeUncompressed /= 2; - - sndFileData.resize(dataSizeUncompressed, 0); - castedDataSize = sndFileData.size() / sizeof(int16_t); - castedData = reinterpret_cast(sndFileData.data()); - } - else if (originalRecord.channels > channels) - { - assert(channels == 1); - assert(originalRecord.channels == 2); - - channels = 2; - dataSizeUncompressed *= 2; - - sndFileData.resize(dataSizeUncompressed, 0); - castedDataSize = sndFileData.size() / sizeof(int16_t); - castedData = reinterpret_cast(sndFileData.data()); - - for (int64_t i = (castedDataSize / 2) - 1; i >= 0; --i) - { - castedData[i * 2] = castedData[i]; - castedData[i * 2 + 1] = castedData[i]; - } - } - } - - if (options.common.fixSampleRate) - { - if (originalRecord.sampleRate != sampleRate) - { - SRC_DATA convData; - convData.src_ratio = static_cast(originalRecord.sampleRate) / sampleRate; - - thread_local static std::vector convertedInSndFileData; - convertedInSndFileData.resize(castedDataSize, 0); - src_short_to_float_array(castedData, convertedInSndFileData.data(), - static_cast(castedDataSize)); - convData.data_in = convertedInSndFileData.data(); - convData.input_frames = static_cast(castedDataSize / channels); - - // UINT16_MAX is just an extra buffer space in case calculation is wrong, but src_ratio * in_size should be - // enough - thread_local static std::vector convertedOutSndFileData; - convertedOutSndFileData.resize(static_cast(convData.src_ratio * castedDataSize) + UINT16_MAX, 0); - convData.data_out = convertedOutSndFileData.data(); - convData.output_frames = static_cast(convertedOutSndFileData.size() / channels); - - const auto retVal = src_simple(&convData, SRC_SINC_BEST_QUALITY, channels); - if (retVal != 0 || convData.input_frames != convData.input_frames_used) - { - DisplayWarning(LocalizationManager::Get().LocalizeFormat("HITMAN_DIALOG_WARNING_IMPORT_TRANCODING_DATA", src_strerror(retVal)), - LocalizationManager::Get().Localize("MESSAGEBOX_WARNING_GENERIC_TITLE"), false, options); - return false; - } - - sndFileData.resize(convData.output_frames_gen * channels * sizeof(int16_t), 0); - castedDataSize = sndFileData.size() / sizeof(int16_t); - castedData = reinterpret_cast(sndFileData.data()); - - src_float_to_short_array(convertedOutSndFileData.data(), castedData, - static_cast(castedDataSize)); - sndFileData.shrink_to_fit(); - - castedData = reinterpret_cast(sndFileData.data()); - - sampleRate = originalRecord.sampleRate; - dataSizeUncompressed = static_cast(sndFileData.size()); - frames = convData.output_frames_gen; - } - } - - thread_local static std::vector nativeData; - nativeData.clear(); - nativeData.reserve(dataSizeUncompressed); - SF_VIRTUAL_DATA nativeFileData = {nativeData}; - SndfileHandle nativeFile; - - switch (originalRecord.formatTag) - { - case 17: { - if (options.common.transcodeToOriginalFormat) - { - nativeFile = SndfileHandle(g_VirtSndFileIO, &nativeFileData, SFM_WRITE, SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, channels, sampleRate); - break; - } - } - [[fallthrough]]; - case 4096: { - if (options.common.transcodeToOriginalFormat) - { - nativeFile = SndfileHandle(g_VirtSndFileIO, &nativeFileData, SFM_WRITE, SF_FORMAT_OGG | SF_FORMAT_VORBIS, channels, sampleRate); - break; - } - } - [[fallthrough]]; - case 1: { - nativeFile = SndfileHandle(g_VirtSndFileIO, &nativeFileData, SFM_WRITE, SF_FORMAT_WAV | SF_FORMAT_PCM_16, channels, sampleRate); - break; - } - default: { - DisplayError(LocalizationManager::Get().Localize("HITMAN_DIALOG_ERROR_UNKNOWN_FORMAT_IN_ARCHIVE")); - return false; - } - } - - if (!nativeFile) - { - DisplayWarning(LocalizationManager::Get().Localize("HITMAN_DIALOG_WARNING_IMPORT_CREATING_NATIVE_DATA"), - LocalizationManager::Get().Localize("MESSAGEBOX_WARNING_GENERIC_TITLE"), false, options); - return false; - } - - constexpr uint32_t maxFramesPerWrite = UINT16_MAX; - size_t castedDataOffset = 0; - while (frames != 0) - { - const uint32_t framesToWrite = std::min(maxFramesPerWrite, frames); - if (nativeFile.writef(castedData + castedDataOffset, framesToWrite) != framesToWrite) - { - DisplayWarning(LocalizationManager::Get().Localize("HITMAN_DIALOG_WARNING_IMPORT_ENCODING_NATIVE_DATA"), - LocalizationManager::Get().Localize("MESSAGEBOX_WARNING_GENERIC_TITLE"), false, options); - return false; - } - frames -= framesToWrite; - castedDataOffset += framesToWrite * channels; - } - - sf_close(nativeFile.takeOwnership()); - - return ImportNative(nativeData, options, false); -} - -bool HitmanFile::Import(std::vector &inputBytes, const Options& options) -{ - return Import(inputBytes.data(), inputBytes.size(), options); -} - -bool HitmanFile::Import(const StringView8CI &importPath, const Options& options) -{ - auto importData = ReadWholeBinaryFile(importPath); - if (importData.empty()) - return false; - - return Import(importData, options); -} - -bool HitmanFile::ImportNative(char inputBytes[], const size_t inputBytesCount, const Options& options, const bool doHashing) -{ - SF_VIRTUAL_DATA_FIXED virtSndData{inputBytes, static_cast(inputBytesCount)}; - SndfileHandle sndFile(g_VirtSndFileIOFixed, &virtSndData); - if (!sndFile) - { - DisplayWarning(LocalizationManager::Get().Localize("HITMAN_DIALOG_WARNING_IMPORT_LOADING_DATA"), - LocalizationManager::Get().Localize("MESSAGEBOX_WARNING_GENERIC_TITLE"), false, options); - return false; - } - - const auto frames = static_cast(sndFile.frames()); - if (frames == 0) - { - DisplayWarning(LocalizationManager::Get().Localize("HITMAN_DIALOG_WARNING_IMPORT_DECODING_DATA"), - LocalizationManager::Get().Localize("MESSAGEBOX_WARNING_GENERIC_TITLE"), false, options); - return false; - } - - const auto format = sndFile.format(); - const auto channels = static_cast(sndFile.channels()); - const auto dataSizeUncompressed = frames * channels * 2; - const auto sampleRate = sndFile.samplerate(); - - thread_local static std::vector sndFileData; - sndFileData.resize(dataSizeUncompressed / 2, 0); - if (sndFile.readf(sndFileData.data(), frames) != frames) - { - DisplayWarning(LocalizationManager::Get().Localize("HITMAN_DIALOG_WARNING_IMPORT_DECODING_DATA"), - LocalizationManager::Get().Localize("MESSAGEBOX_WARNING_GENERIC_TITLE"), false, options); - return false; - } - - sf_close(sndFile.takeOwnership()); - - if (doHashing) - { - if (options.common.checkOriginality) - archiveRecord.dataXXH3 = XXH3_64bits(sndFileData.data(), dataSizeUncompressed); - - if (!options.common.importOriginalFiles && (originalRecord.dataXXH3 == archiveRecord.dataXXH3)) - return true; - } - - uint16_t inputFormat = UINT16_MAX; - if ((format & SF_FORMAT_WAV) == SF_FORMAT_WAV) - inputFormat = (format & SF_FORMAT_IMA_ADPCM) == SF_FORMAT_IMA_ADPCM ? 17 : 1; - else if ((format & SF_FORMAT_OGG) == SF_FORMAT_OGG) - inputFormat = (format & SF_FORMAT_VORBIS) == SF_FORMAT_VORBIS ? 4096 : UINT16_MAX; - - switch (inputFormat) - { - case 1: { - const auto* riffHeader = reinterpret_cast(inputBytes); - - archiveRecord.dataSizeUncompressed = riffHeader->dataSize; - archiveRecord.dataSize = riffHeader->dataSize; - archiveRecord.sampleRate = riffHeader->fmtSampleRate; - archiveRecord.formatTag = riffHeader->fmtFormat; - archiveRecord.bitsPerSample = riffHeader->fmtBitsPerSample; - archiveRecord.channels = riffHeader->fmtChannels; - archiveRecord.blockAlign = riffHeader->fmtBlockAlign; - archiveRecord.fmtExtra = 1; - - data.resize(riffHeader->dataSize); - memcpy(data.data(), inputBytes + sizeof(RIFFHeaderPCM), riffHeader->dataSize); - - break; - } - case 17: { - const auto* riffHeader = reinterpret_cast(inputBytes); - - archiveRecord.dataSizeUncompressed = riffHeader->factSamplesCount * sizeof(int16_t); - archiveRecord.dataSize = riffHeader->dataSize; - archiveRecord.sampleRate = riffHeader->fmtSampleRate; - archiveRecord.formatTag = riffHeader->fmtFormat; - archiveRecord.bitsPerSample = riffHeader->fmtBitsPerSample; - archiveRecord.channels = riffHeader->fmtChannels; - archiveRecord.blockAlign = riffHeader->fmtBlockAlign; - archiveRecord.fmtExtra = riffHeader->fmtExtra; - - data.resize(riffHeader->dataSize); - memcpy(data.data(), inputBytes + sizeof(RIFFHeaderADPCM), riffHeader->dataSize); - - break; - } - case 4096: { - archiveRecord.dataSizeUncompressed = dataSizeUncompressed; - archiveRecord.dataSize = static_cast(inputBytesCount); - archiveRecord.sampleRate = sampleRate; - archiveRecord.formatTag = 4096; - archiveRecord.bitsPerSample = 16; - archiveRecord.channels = channels; - archiveRecord.blockAlign = channels * sizeof(int16_t); - archiveRecord.fmtExtra = 1; - - data.resize(inputBytesCount); - memcpy(data.data(), inputBytes, inputBytesCount); - - break; - } - default: { - DisplayError(LocalizationManager::Get().Localize("HITMAN_DIALOG_ERROR_UNKNOWN_FORMAT_IN_ARCHIVE")); - return false; - } - } - - data.shrink_to_fit(); - return true; -} - -bool HitmanFile::ImportNative(std::vector &inputBytes, const Options& options, const bool doHashing) -{ - return ImportNative(inputBytes.data(), inputBytes.size(), options, doHashing); -} - -bool HitmanFile::ImportNative(const StringView8CI &importPath, const Options& options, const bool doHashing) -{ - auto importData = ReadWholeBinaryFile(importPath); - if (importData.empty()) - return false; - - return ImportNative(importData, options, doHashing); -} - -bool HitmanFile::Export(std::vector &outputBytes) const -{ - outputBytes.clear(); - - if (archiveRecord.formatTag == 1) - { - RIFFHeaderPCM riffHeader; - riffHeader.riffSize = archiveRecord.dataSize; - riffHeader.fmtFormat = archiveRecord.formatTag; - riffHeader.fmtChannels = archiveRecord.channels; - riffHeader.fmtSampleRate = archiveRecord.sampleRate; - riffHeader.fmtAvgBytesRate = archiveRecord.sampleRate * archiveRecord.bitsPerSample * archiveRecord.channels / 8; - riffHeader.fmtBlockAlign = archiveRecord.blockAlign; - riffHeader.fmtBitsPerSample = archiveRecord.bitsPerSample; - riffHeader.dataSize = archiveRecord.dataSize; - - outputBytes.resize(sizeof(riffHeader)); - memcpy(outputBytes.data(), &riffHeader, sizeof(riffHeader)); - } - else if (archiveRecord.formatTag == 17) - { - RIFFHeaderADPCM riffHeader; - riffHeader.riffSize = archiveRecord.dataSize; - riffHeader.fmtFormat = archiveRecord.formatTag; - riffHeader.fmtChannels = archiveRecord.channels; - riffHeader.fmtSampleRate = archiveRecord.sampleRate; - riffHeader.fmtAvgBytesRate = archiveRecord.sampleRate * archiveRecord.blockAlign / - ((archiveRecord.blockAlign - archiveRecord.channels * 4) * (archiveRecord.channels ^ 3) + 1); - riffHeader.fmtBlockAlign = archiveRecord.blockAlign; - riffHeader.fmtBitsPerSample = archiveRecord.bitsPerSample; - riffHeader.fmtExtra = archiveRecord.fmtExtra; - riffHeader.factSamplesCount = archiveRecord.dataSizeUncompressed / sizeof(int16_t); - riffHeader.dataSize = archiveRecord.dataSize; - - outputBytes.resize(sizeof(riffHeader), 0); - memcpy(outputBytes.data(), &riffHeader, sizeof(riffHeader)); - } - else if (archiveRecord.formatTag == 4096) - { - // NOTE: nothing to do, OGG files are completely contained in data - } - else - { - DisplayError(LocalizationManager::Get().Localize("HITMAN_DIALOG_ERROR_UNKNOWN_FORMAT_IN_ARCHIVE")); - return false; - } - - const auto dataOffset = outputBytes.size(); - outputBytes.resize(outputBytes.size() + data.size(), 0); - memcpy(outputBytes.data() + dataOffset, data.data(), data.size()); - - return true; -} - -bool HitmanFile::Export(const StringView8CI &export_path_view, const bool fixExtension) const -{ - thread_local static std::vector exportData; - if (!Export(exportData)) - return false; - - String8CI exportPath; - if (fixExtension) - { - if (archiveRecord.formatTag == 1 || archiveRecord.formatTag == 17) - { - if (export_path_view.path().extension() != StringView8CI(".wav")) - exportPath = ChangeExtension(export_path_view, ".wav"); - } - else if (archiveRecord.formatTag == 4096) - { - if (export_path_view.path().extension() != StringView8CI(".ogg")) - exportPath = ChangeExtension(export_path_view, ".ogg"); - } - } - if (exportPath.empty()) - exportPath = export_path_view; - - auto exportPathFS = exportPath.path(); - create_directories(exportPathFS.parent_path()); - - const auto oldSync = std::ios_base::sync_with_stdio(false); - - std::ofstream exportBin(exportPathFS, std::ios::binary | std::ios::trunc); - exportBin.write(exportData.data(), static_cast(exportData.size())); - - std::ios_base::sync_with_stdio(oldSync); - - return true; -} - -bool HitmanDialog::Clear(const bool retVal) -{ - fileMap.clear(); - - return ArchiveDialog::Clear(retVal); -} - -bool HitmanDialog::GenerateOriginalData() -{ - const auto dataPath = originalDataPath.path(); - create_directories(dataPath.parent_path()); - - const auto oldSync = std::ios_base::sync_with_stdio(false); - - std::ofstream genFile(dataPath, std::ios::binary | std::ios::trunc); - uint64_t entriesCount = fileMap.size(); - genFile.write(reinterpret_cast(&entriesCount), sizeof(entriesCount)); - - thread_local static std::vector exportBytes; - for (auto &[filePath, file] : fileMap) - { - auto &archiveFile = GetFile(filePath); - ZeroMemory(&file.originalRecord, sizeof(file).originalRecord); - - file.Export(exportBytes); - - SF_VIRTUAL_DATA_FIXED virtData{exportBytes.data(), static_cast(exportBytes.size())}; - SndfileHandle sndFile(g_VirtSndFileIOFixed, &virtData); - if (!sndFile) - { - assert(false); - return false; - } - - const auto frames = static_cast(sndFile.frames()); - const auto channels = static_cast(sndFile.channels()); - const auto dataUncompressedSize = frames * channels * sizeof(int16_t); - - std::vector sndFileData(dataUncompressedSize / sizeof(int16_t), 0); - if (sndFile.readf(sndFileData.data(), frames) != frames) - { - assert(false); - return false; - } - - sf_close(sndFile.takeOwnership()); - - file.archiveRecord.dataXXH3 = XXH3_64bits(sndFileData.data(), dataUncompressedSize); - file.originalRecord = file.archiveRecord; - - archiveFile.original = true; - - genFile.write(reinterpret_cast(&file.originalRecord), sizeof(file).originalRecord); - } - - std::ios_base::sync_with_stdio(oldSync); - - return true; -} - -bool HitmanDialog::LoadOriginalData() -{ - const auto dataPath = originalDataPath.path(); - if (!exists(dataPath)) - return GenerateOriginalData(); - - const auto oldSync = std::ios_base::sync_with_stdio(false); - - std::ifstream genFile(dataPath, std::ios::binary); - uint64_t entriesCount = 0; - genFile.read(reinterpret_cast(&entriesCount), sizeof(entriesCount)); - - thread_local static std::vector exportBytes; - for (auto &[filePath, file] : fileMap) - { - auto &archiveFile = GetFile(filePath); - auto &originalRecord = file.originalRecord; - genFile.read(reinterpret_cast(&originalRecord), sizeof(originalRecord)); - - file.archiveRecord.dataXXH3 = file.originalRecord.dataXXH3; - archiveFile.original = file.originalRecord == file.archiveRecord; - - // skip hash check if format is of type we cannot import - if (archiveFile.original == false || (file.archiveRecord.formatTag != 1 && file.archiveRecord.formatTag != 17)) - continue; - - file.Export(exportBytes); - - SF_VIRTUAL_DATA_FIXED virtData{exportBytes.data(), static_cast(exportBytes.size())}; - SndfileHandle sndFile(g_VirtSndFileIOFixed, &virtData); - if (!sndFile) - { - assert(false); - return false; - } - - const auto frames = static_cast(sndFile.frames()); - const auto channels = static_cast(sndFile.channels()); - const auto dataUncompressedSize = frames * channels * sizeof(int16_t); - - std::vector sndFileData(dataUncompressedSize / sizeof(int16_t), 0); - if (sndFile.readf(sndFileData.data(), frames) != frames) - { - assert(false); - return false; - } - - sf_close(sndFile.takeOwnership()); - - file.archiveRecord.dataXXH3 = XXH3_64bits(sndFileData.data(), dataUncompressedSize); - archiveFile.original &= originalRecord.dataXXH3 == file.archiveRecord.dataXXH3; - } - - std::ios_base::sync_with_stdio(oldSync); - - return true; -} - -bool HitmanDialog::ImportSingleHitmanFile(HitmanFile &hitmanFile, const StringView8CI &hitmanFilePath, std::vector &data, const bool doConversion, const Options &options) -{ - if (doConversion) - hitmanFile.Import(data, options); - else - hitmanFile.ImportNative(data, options, true); - - auto &archiveFile = GetFile(hitmanFilePath); - - if (options.common.checkOriginality && hitmanFile.originalRecord.dataXXH3 != 0) - archiveFile.original = hitmanFile.originalRecord == hitmanFile.archiveRecord; - - archiveFile.dirty = archiveFile.dirty || !archiveFile.original; - - return true; -} - -bool HitmanDialog::ImportSingleHitmanFile(HitmanFile &hitmanFile, const StringView8CI &hitmanFilePath, const StringView8CI &importFilePath, const Options &options) -{ - auto inputData = ReadWholeBinaryFile(importFilePath); - return ImportSingleHitmanFile(hitmanFile, hitmanFilePath, inputData, !options.common.directImport, options); -} - -bool HitmanDialog::ExportSingle(const StringView8CI &exportFolderPath, const StringView8CI &exportFilePath, const Options &) const -{ - const auto fileMapIt = fileMap.find(exportFilePath); - if (fileMapIt == fileMap.cend()) - return false; - - const String8CI exportPath = exportFolderPath.path() / exportFilePath.path(); - return fileMapIt->second.Export(exportPath, true); -} - -void HitmanDialog::ReloadOriginalData() -{ - if (IsInProgress()) - { - needsOriginalDataReload = true; - return; - } - - if (!originalDataPath.empty() && !fileMap.empty()) - { - progressMessage = LocalizationManager::Get().Localize("HITMAN_DIALOG_LOADING_ORIGINAL_RECORDS"); - progressNext = 0; - progressNextTotal = 1; - - progressTask = std::async(std::launch::async, [this] { - LoadOriginalData(); - - std::unique_lock progressMessageLock(progressMessageMutex); - progressMessage.clear(); - progressNext = 1; - }); - } - - needsOriginalDataReload = false; -} - -void HitmanDialog::DrawHitmanDialog(const StringView8CI &dialogName, const StringView8CI &filters, const StringView8CI &defaultFilename) -{ - if (needsOriginalDataReload) - ReloadOriginalData(); - - DrawBaseDialog(dialogName, filters, defaultFilename); -} diff --git a/src/HitmanDialog.hpp b/src/HitmanDialog.hpp deleted file mode 100644 index 0a92c1d..0000000 --- a/src/HitmanDialog.hpp +++ /dev/null @@ -1,66 +0,0 @@ -// -// Created by Andrej Redeky. -// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. -// SPDX-License-Identifier: EUPL-1.2 -// - -#pragma once - -#include "ArchiveDialog.hpp" - -struct HitmanSoundRecord -{ - uint64_t dataXXH3 = 0; - uint32_t dataSizeUncompressed = 0; - uint32_t dataSize = 0; - uint32_t sampleRate = 0; - uint16_t formatTag = 0; - uint16_t bitsPerSample = 0; - uint16_t channels = 0; - uint16_t blockAlign = 0; - uint16_t fmtExtra = 0; - - auto operator<=>(const HitmanSoundRecord & other) const = default; -}; - -struct HitmanFile -{ - bool Import(char inputBytes[], size_t inputBytesCount, const Options& options); - bool Import(std::vector &inputBytes, const Options& options); - bool Import(const StringView8CI &importPath, const Options& options); - - bool ImportNative(char inputBytes[], size_t inputBytesCount, const Options& options, bool doHashing); - bool ImportNative(std::vector &inputBytes, const Options& options, bool doHashing); - bool ImportNative(const StringView8CI &importPath, const Options& options, bool doHashing); - - bool Export(std::vector &outputBytes) const; - bool Export(const StringView8CI &exportPath, bool fixExtension) const; - - HitmanSoundRecord originalRecord; - HitmanSoundRecord archiveRecord; - std::vector data; -}; - -class HitmanDialog : public ArchiveDialog -{ -public: - bool Clear(bool retVal = false) override; - - bool GenerateOriginalData(); - - bool LoadOriginalData(); - - bool ImportSingleHitmanFile(HitmanFile &hitmanFile, const StringView8CI &hitmanFilePath, std::vector &data, bool doConversion, const Options &options); - - bool ImportSingleHitmanFile(HitmanFile &hitmanFile, const StringView8CI &hitmanFilePath, const StringView8CI &importFilePath, const Options &options); - - bool ExportSingle(const StringView8CI &exportFolderPath, const StringView8CI &exportFilePath, const Options &options) const override; - - void ReloadOriginalData(); - - void DrawHitmanDialog(const StringView8CI &dialogName, const StringView8CI &filters, const StringView8CI &defaultFilename); - - OrderedMap fileMap; - String8CI originalDataPath; - bool needsOriginalDataReload = false; -}; diff --git a/src/Main.cpp b/src/Main.cpp deleted file mode 100644 index 4d00981..0000000 --- a/src/Main.cpp +++ /dev/null @@ -1,303 +0,0 @@ -// -// Created by Andrej Redeky. -// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. -// SPDX-License-Identifier: EUPL-1.2 -// - -#include "Precompiled.hpp" - -#include "Config.hpp" - -#include "Hitman1Dialog.hpp" -#include "Hitman23Dialog.hpp" -#include "Hitman4Dialog.hpp" - -#include "backends/imgui_impl_opengl3.h" -#include "backends/imgui_impl_sdl2.h" - -bool BuildFontAtlas() -{ - if (!GlyphRangesBuilder::Get().NeedsBuild()) - return true; - - auto fontsPath = GetProgramPath().path(); - fontsPath /= L"data"; - fontsPath /= L"fonts"; - if (!exists(fontsPath)) - return false; - - ImFontGlyphRangesBuilder builder; - - const auto glyphRanges = GlyphRangesBuilder::Get().Build(); - for (const auto& glyphRange : glyphRanges) - { - const uint32_t translatedGlyphRange[3]{glyphRange.first, glyphRange.second, 0}; - builder.AddRanges(translatedGlyphRange); - } - - static ImVector imguiRanges; - imguiRanges.clear(); - - builder.BuildRanges(&imguiRanges); - - ImFontConfig config; - config.SizePixels = 18; - config.OversampleH = 3; - config.OversampleV = 1; - config.MergeMode = false; - - const ImGuiIO &io = ImGui::GetIO(); - io.Fonts->Clear(); - - const auto fonts = GetAllFilesInDirectory(String8CI(fontsPath), "", false); - for (const auto& font : fonts) - { - const auto fontExtension = font.path().extension(); - if (fontExtension != StringViewWCI(L".ttf") && fontExtension != StringViewWCI(L".otf")) - continue; - - io.Fonts->AddFontFromFileTTF(font.c_str(), config.SizePixels, &config, imguiRanges.Data); - config.MergeMode = true; - } - - if (!config.MergeMode) - io.Fonts->AddFontDefault(&config); - - ImGui_ImplOpenGL3_DestroyFontsTexture(); - ImGui_ImplOpenGL3_CreateFontsTexture(); - - return true; -} - -int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) -{ - // TODO - make testing stuff better, this is very primitive and ugly (and inefficient in general... but does the job for now...) - void RunTests(); - RunTests(); - - auto dataPath = GetProgramPath().path(); - if (dataPath.empty()) - return -1; - - dataPath /= L"data"; - if (!exists(dataPath)) - return -2; - - const auto localizationPath = dataPath / L"localization"; - if (!exists(localizationPath)) - return -3; - - const auto fontsPath = dataPath / L"fonts"; - if (!exists(fontsPath)) - return -4; - - const auto recordsData = dataPath / L"records"; - if (!exists(recordsData)) - return -5; - - const auto localizationFilePaths = GetAllFilesInDirectory(String8CI(localizationPath), ".toml", false); - if (localizationFilePaths.empty()) - return -6; - - bool foundEnglish = false; - for (const auto& localizationFilePath : localizationFilePaths) - { - if (!LocalizationManager::Get().LoadLocalization(localizationFilePath)) - return -7; - - if (localizationFilePath.path().stem() == StringViewWCI(L"English")) - foundEnglish = true; - } - if (!foundEnglish) - return -8; - - if (!LocalizationManager::Get().SetDefaultLanguage("English")) - return -9; - - Options::Get().Load(); - Options::Get().Save(); - - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0) - { - DisplayError(LocalizationManager::Get().LocalizeFormat("ARCHIVE_DIALOG_IMPORT_PROGRESS_IMPORTING_FILE", SDL_GetError())); - return -10; - } - - const char *glsl_version = "#version 130"; - SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); - -#ifdef SDL_HINT_IME_SHOW_UI - SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1"); -#endif - - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); - SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); - constexpr auto window_flags = - static_cast(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); - SDL_Window *window = - SDL_CreateWindow(G1AT_TITLE, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, window_flags); - const auto gl_context = SDL_GL_CreateContext(window); - SDL_GL_MakeCurrent(window, gl_context); - SDL_GL_SetSwapInterval(1); - - IMGUI_CHECKVERSION(); - ImGui::CreateContext(); - ImGuiIO &io = ImGui::GetIO(); - io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; - io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; - io.IniFilename = nullptr; - io.LogFilename = nullptr; - - ImGui::StyleColorsDark(); - - ImGui_ImplSDL2_InitForOpenGL(window, gl_context); - ImGui_ImplOpenGL3_Init(glsl_version); - - constexpr ImVec4 clear_color(0.45f, 0.55f, 0.60f, 1.00f); - - bool done = false; - while (!done) - { - SDL_Event event; - while (SDL_PollEvent(&event)) - { - ImGui_ImplSDL2_ProcessEvent(&event); - - switch (event.type) - { - case SDL_QUIT: { - done = true; - break; - } - case SDL_WINDOWEVENT: { - done = event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window); - break; - } - } - } - - done &= !Hitman1Dialog::Get().IsInProgress() && !Hitman23Dialog::Get().IsInProgress(); - - if (done) - { - switch (Hitman1Dialog::Get().UnsavedChangesPopup()) - { - case 1: { - Hitman1Dialog::Get().Save(Hitman1Dialog::Get().GetPath(), false); - break; - } - case 0: { - break; - } - default: - case -1: { - done = false; - break; - } - } - } - - if (done) - { - switch (Hitman23Dialog::Get().UnsavedChangesPopup()) - { - case 1: { - Hitman23Dialog::Get().Save(Hitman23Dialog::Get().GetPath(), false); - break; - } - case 0: { - break; - } - default: - case -1: { - done = false; - break; - } - } - } - - if (done) - { - switch (Hitman4Dialog::Get().UnsavedChangesPopup()) - { - case 1: { - Hitman4Dialog::Get().Save(Hitman4Dialog::Get().GetPath(), false); - break; - } - case 0: { - break; - } - default: - case -1: { - done = false; - break; - } - } - } - - BuildFontAtlas(); - - ImGui_ImplOpenGL3_NewFrame(); - ImGui_ImplSDL2_NewFrame(); - ImGui::NewFrame(); - - int32_t windowWidth = 0; - int32_t windowHeight = 0; - SDL_GetWindowSize(window, &windowWidth, &windowHeight); - - ImGui::SetNextWindowPos({}, ImGuiCond_Always); - ImGui::SetNextWindowSize({static_cast(windowWidth), static_cast(windowHeight)}, ImGuiCond_Always); - ImGui::Begin(G1AT_NAME, nullptr, - ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); - - if (ImGui::BeginTabBar("##ToolsTab")) - { - Hitman1Dialog::Get().DrawDialog(); - Hitman23Dialog::Get().DrawDialog(); - -#ifdef _DEBUG - Hitman4Dialog::Get().DrawDialog(); -#endif - - Options::Get().DrawDialog(); - - ImGui::EndTabBar(); - } - - ImGui::End(); - - ImGui::Render(); - glViewport(0, 0, static_cast(io.DisplaySize.x), static_cast(io.DisplaySize.y)); - glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, - clear_color.w); - glClear(GL_COLOR_BUFFER_BIT); - ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); - - if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) - { - auto *backup_current_window = SDL_GL_GetCurrentWindow(); - const auto backup_current_context = SDL_GL_GetCurrentContext(); - ImGui::UpdatePlatformWindows(); - ImGui::RenderPlatformWindowsDefault(); - SDL_GL_MakeCurrent(backup_current_window, backup_current_context); - } - - SDL_GL_SwapWindow(window); - } - - ImGui_ImplOpenGL3_Shutdown(); - ImGui_ImplSDL2_Shutdown(); - ImGui::DestroyContext(); - - SDL_GL_DeleteContext(gl_context); - SDL_DestroyWindow(window); - SDL_Quit(); - - Options::Get().Save(); - - return 0; -} diff --git a/src/Options.cpp b/src/Options.cpp deleted file mode 100644 index 5532efc..0000000 --- a/src/Options.cpp +++ /dev/null @@ -1,168 +0,0 @@ -// -// Created by Andrej Redeky. -// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. -// SPDX-License-Identifier: EUPL-1.2 - -#include "Precompiled.hpp" - -#include "Options.hpp" - -#include "Hitman1Dialog.hpp" -#include "Hitman23Dialog.hpp" -#include "Hitman4Dialog.hpp" - -void CommonSettings::Load(const toml::table &aInputRoot) -{ - ResetToDefaults(); - - const auto& commonTable = aInputRoot["common"]; - - disableWarnings = commonTable["disable_warnings"].value_or(disableWarnings); - checkOriginality = commonTable["check_originality"].value_or(checkOriginality); - importOriginalFiles = commonTable["import_original_files"].value_or(importOriginalFiles); - fixChannels = commonTable["fix_channels"].value_or(fixChannels); - fixSampleRate = commonTable["fix_sample_rate"].value_or(fixSampleRate); - transcodeToOriginalFormat = commonTable["transcode_to_original_format"].value_or(transcodeToOriginalFormat); - directImport = commonTable["direct_import"].value_or(directImport); - - LocalizationManager::Get().SetLanguage(commonTable["language"].value_or(LocalizationManager::Get().GetLanguage().native())); -} - -void CommonSettings::Save(toml::table &aOutputRoot) const -{ - toml::table commonTable; - - commonTable.emplace("disable_warnings", disableWarnings); - commonTable.emplace("check_originality", checkOriginality); - commonTable.emplace("import_original_files", importOriginalFiles); - commonTable.emplace("fix_channels", fixChannels); - commonTable.emplace("fix_sample_rate", fixSampleRate); - commonTable.emplace("transcode_to_original_format", transcodeToOriginalFormat); - commonTable.emplace("direct_import", directImport); - - commonTable.emplace("language", LocalizationManager::Get().GetLanguage().native()); - - aOutputRoot.emplace("common", std::move(commonTable)); -} - -void CommonSettings::ResetToDefaults() -{ - *this = {}; -} - -void CommonSettings::DrawDialog() -{ - if (!ImGui::TreeNodeEx(LocalizationManager::Get().Localize("SETTINGS_DIALOG_COMMON_GROUP").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) - return; - - if (ImGui::BeginCombo(LocalizationManager::Get().Localize("SETTINGS_DIALOG_LANGUAGE").c_str(), LocalizationManager::Get().GetLanguage().c_str())) - { - const auto availableLanguages = LocalizationManager::Get().GetAvailableLanguages(); - for (const auto& language : availableLanguages) - { - bool selected = LocalizationManager::Get().GetLanguage() == language; - if (ImGui::Selectable(language.c_str(), &selected)) - LocalizationManager::Get().SetLanguage(language); - } - ImGui::EndCombo(); - } - - ImGui::Checkbox(LocalizationManager::Get().Localize("SETTINGS_DIALOG_DISABLE_WARNINGS").c_str(), &disableWarnings); - - const bool prevCheckOriginality = checkOriginality; - ImGui::Checkbox(LocalizationManager::Get().Localize("SETTINGS_DIALOG_CHECK_DATA_ORIGINALITY").c_str(), &checkOriginality); - - if (!prevCheckOriginality && checkOriginality) - { - Hitman1Dialog::Get().ReloadOriginalData(); - Hitman23Dialog::Get().ReloadOriginalData(); - Hitman4Dialog::Get().ReloadOriginalData(); - } - - if (!checkOriginality && !importOriginalFiles) - importOriginalFiles = true; - - if (!checkOriginality) - ImGui::BeginDisabled(); - - ImGui::TreePush(&checkOriginality); - - ImGui::Checkbox(LocalizationManager::Get().Localize("SETTINGS_DIALOG_IMPORT_ORIGINAL_FILES").c_str(), - &importOriginalFiles); - - ImGui::TreePop(); - - if (!checkOriginality) - ImGui::EndDisabled(); - - ImGui::Checkbox(LocalizationManager::Get().Localize("SETTINGS_DIALOG_DIRECT_IMPORT").c_str(), - &directImport); - - if (directImport) - ImGui::BeginDisabled(); - - ImGui::TreePush(&directImport); - - fixChannels &= !directImport; - ImGui::Checkbox(LocalizationManager::Get().Localize("SETTINGS_DIALOG_FIX_CHANNELS").c_str(), &fixChannels); - - fixSampleRate &= !directImport; - ImGui::Checkbox(LocalizationManager::Get().Localize("SETTINGS_DIALOG_FIX_SAMPLE_RATE").c_str(), &fixSampleRate); - - transcodeToOriginalFormat &= !directImport; - ImGui::Checkbox(LocalizationManager::Get().Localize("SETTINGS_DIALOG_TRANSCODE_TO_ORIGINAL_FORMAT").c_str(), &transcodeToOriginalFormat); - - ImGui::TreePop(); - - if (directImport) - ImGui::EndDisabled(); - - ImGui::TreePop(); -} - -void Options::Load() -{ - auto optionsPath = GetProgramPath().path(); - if (optionsPath.empty()) - return; - - optionsPath /= L"config.toml"; - - auto config = toml::parse_file(optionsPath.native()); - if (config.failed()) - return; - - common.Load(config); -} - -void Options::Save() const -{ - auto optionsPath = GetProgramPath().path(); - if (optionsPath.empty()) - return; - - optionsPath /= L"config.toml"; - - toml::table config; - - common.Save(config); - - std::ofstream(optionsPath, std::ios::trunc) << config; -} - -void Options::ResetToDefaults() -{ - common.ResetToDefaults(); - - Save(); -} - -void Options::DrawDialog() -{ - if (!ImGui::BeginTabItem(LocalizationManager::Get().Localize("SETTINGS_DIALOG_TITLE").c_str())) - return; - - common.DrawDialog(); - - ImGui::EndTabItem(); -} diff --git a/src/Options.hpp b/src/Options.hpp deleted file mode 100644 index e6ed12c..0000000 --- a/src/Options.hpp +++ /dev/null @@ -1,38 +0,0 @@ -// -// Created by Andrej Redeky. -// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. -// SPDX-License-Identifier: EUPL-1.2 - -#pragma once - -class CommonSettings -{ -public: - void Load(const toml::table &aInputRoot); - void Save(toml::table &aOutputRoot) const; - void ResetToDefaults(); - - void DrawDialog(); - - [[nodiscard]] auto operator<=>(const CommonSettings &) const = default; - - bool disableWarnings{false}; - bool checkOriginality{true}; - bool importOriginalFiles{false}; - bool fixChannels{true}; - bool fixSampleRate{true}; - bool transcodeToOriginalFormat{true}; - bool directImport{false}; -}; - -class Options : public Singleton -{ -public: - void Load(); - void Save() const; - void ResetToDefaults(); - - void DrawDialog(); - - CommonSettings common{}; -}; diff --git a/src/Platform/Linux/DPIHandler.cpp b/src/Platform/Linux/DPIHandler.cpp new file mode 100644 index 0000000..5d39dcf --- /dev/null +++ b/src/Platform/Linux/DPIHandler.cpp @@ -0,0 +1,43 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 +// + +#include + +#include + +#include + +namespace App { + +float DPIHandler::get_scale() { + APP_PROFILE_FUNCTION(); + + constexpr int display_index{0}; + const float default_dpi{96.0F}; + float dpi{default_dpi}; + + SDL_GetDisplayDPI(display_index, nullptr, &dpi, nullptr); + + return dpi / default_dpi; +} + +WindowSize DPIHandler::get_dpi_aware_window_size(const Window::Settings& settings) { + APP_PROFILE_FUNCTION(); + + return {settings.width, settings.height}; +} + +void DPIHandler::set_render_scale([[maybe_unused]] SDL_Renderer* renderer) { + APP_PROFILE_FUNCTION(); + // do nothing +} + +void DPIHandler::set_global_font_scaling([[maybe_unused]] ImGuiIO* io) { + APP_PROFILE_FUNCTION(); + // do nothing +} + +} // namespace App diff --git a/src/Platform/Linux/Resources.cpp b/src/Platform/Linux/Resources.cpp new file mode 100644 index 0000000..2dd5c39 --- /dev/null +++ b/src/Platform/Linux/Resources.cpp @@ -0,0 +1,26 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 +// + +#include + +#include + +namespace App { + +static const std::string BASE_PATH{SDL_GetBasePath()}; + +std::filesystem::path Resources::resource_path(const std::filesystem::path& file_path) { + std::filesystem::path font_path{BASE_PATH}; + font_path /= "../share"; + font_path /= "fonts" / file_path; + return font_path; +} + +std::filesystem::path Resources::font_path(const std::string_view& font_file) { + return resource_path(font_file); +} + +} // namespace App diff --git a/src/Platform/Mac/DPIHandler.cpp b/src/Platform/Mac/DPIHandler.cpp new file mode 100644 index 0000000..3321355 --- /dev/null +++ b/src/Platform/Mac/DPIHandler.cpp @@ -0,0 +1,48 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 +// + +#include + +#include + +#include + +namespace App { + +float DPIHandler::get_scale() { + APP_PROFILE_FUNCTION(); + + constexpr int display_index{0}; + // @todo: This should be 72.0F on Mac, but it seems like it is not. I'm not + // sure why, but this works ¯\_(ツ)_/¯ + const float default_dpi{96.0F}; + float dpi{default_dpi}; + + SDL_GetDisplayDPI(display_index, nullptr, &dpi, nullptr); + + return std::floor(dpi / default_dpi); +} + +WindowSize DPIHandler::get_dpi_aware_window_size(const Window::Settings& settings) { + APP_PROFILE_FUNCTION(); + + return {settings.width, settings.height}; +} + +void DPIHandler::set_render_scale(SDL_Renderer* renderer) { + APP_PROFILE_FUNCTION(); + + auto scale{get_scale()}; + SDL_RenderSetScale(renderer, scale, scale); +} + +void DPIHandler::set_global_font_scaling(ImGuiIO* io) { + APP_PROFILE_FUNCTION(); + + io->FontGlobalScale = 1.0F / get_scale(); +} + +} // namespace App diff --git a/src/Platform/Mac/Resources.cpp b/src/Platform/Mac/Resources.cpp new file mode 100644 index 0000000..e50d6a5 --- /dev/null +++ b/src/Platform/Mac/Resources.cpp @@ -0,0 +1,25 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 +// + +#include + +#include + +namespace App { + +static const std::string BASE_PATH{SDL_GetBasePath()}; + +std::filesystem::path Resources::resource_path(const std::filesystem::path& file_path) { + std::filesystem::path font_path{BASE_PATH}; + font_path /= file_path; + return font_path; +} + +std::filesystem::path Resources::font_path(const std::string_view& font_file) { + return resource_path(font_file); +} + +} // namespace App diff --git a/src/Platform/Windows/DPIHandler.cpp b/src/Platform/Windows/DPIHandler.cpp new file mode 100644 index 0000000..2310c7e --- /dev/null +++ b/src/Platform/Windows/DPIHandler.cpp @@ -0,0 +1,46 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 +// + +#include + +#include + +#include + +namespace App { + +float DPIHandler::get_scale() { + APP_PROFILE_FUNCTION(); + + constexpr int display_index{0}; + const float default_dpi{96.0F}; + float dpi{default_dpi}; + + SDL_GetDisplayDPI(display_index, nullptr, &dpi, nullptr); + + return dpi / default_dpi; +} + +WindowSize DPIHandler::get_dpi_aware_window_size(const Window::Settings& settings) { + APP_PROFILE_FUNCTION(); + + const float scale{DPIHandler::get_scale()}; + const int width{static_cast(static_cast(settings.width) * scale)}; + const int height{static_cast(static_cast(settings.height) * scale)}; + return {width, height}; +} + +void DPIHandler::set_render_scale([[maybe_unused]] SDL_Renderer* renderer) { + APP_PROFILE_FUNCTION(); + // do nothing +} + +void DPIHandler::set_global_font_scaling([[maybe_unused]] ImGuiIO* io) { + APP_PROFILE_FUNCTION(); + // do nothing +} + +} // namespace App diff --git a/src/Platform/Windows/Resources.cpp b/src/Platform/Windows/Resources.cpp new file mode 100644 index 0000000..dd87f2e --- /dev/null +++ b/src/Platform/Windows/Resources.cpp @@ -0,0 +1,25 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 +// + +#include + +#include + +namespace App { + +static const std::string BASE_PATH{SDL_GetBasePath()}; + +std::filesystem::path Resources::resource_path(const std::filesystem::path& file_path) { + std::filesystem::path font_path{BASE_PATH}; + font_path /= "../share" / file_path; + return font_path; +} + +std::filesystem::path Resources::font_path(const std::string_view& font_file) { + return resource_path("fonts") / font_file; +} + +} // namespace App diff --git a/src/Precompiled.h b/src/Precompiled.h index dcd7aa8..9efab13 100644 --- a/src/Precompiled.h +++ b/src/Precompiled.h @@ -6,18 +6,17 @@ #pragma once +#define SDL_MAIN_HANDLED 1 + #include #include - -#include -#include #include -#include -#include - +#include #include #include #include #include -#include + +#include +#include diff --git a/src/Precompiled.hpp b/src/Precompiled.hpp index 3ec1cb6..fce5348 100644 --- a/src/Precompiled.hpp +++ b/src/Precompiled.hpp @@ -9,166 +9,43 @@ extern "C" { -#include "Precompiled.h" +#include } +#include +#include + +using namespace UTF; + +inline GlyphRangesBuilder g_GlyphRangesBuilder; +inline LocalizationManager g_LocalizationManager{g_GlyphRangesBuilder}; + #include +#include +#include #include -#include -#include +#include +#include +#include +#include +#include #include #include +#include #include #include +#include #include #include -#include -#include +#include +#include #include +#include #include #include +#include +#include #include #include - -struct SF_VIRTUAL_DATA_FIXED -{ - char* data = nullptr; - sf_count_t dataSize = 0; - sf_count_t offset = 0; -}; - -struct SF_VIRTUAL_DATA -{ - std::vector &data; - sf_count_t offset = 0; -}; - -inline SF_VIRTUAL_IO g_VirtSndFileIOFixed { - .get_filelen = [](void *user_data) -> sf_count_t { - const auto* virtData = static_cast(user_data); - return virtData->dataSize; - }, - .seek = [](const sf_count_t offset, const int whence, void *user_data) -> sf_count_t { - auto* virtData = static_cast(user_data); - - switch (whence) - { - case SEEK_SET: - virtData->offset = offset; - break; - - case SEEK_CUR: - virtData->offset += offset; - break; - - case SEEK_END: - virtData->offset = virtData->dataSize + offset; - break; - - default: - break; - } - - assert(virtData->offset <= virtData->dataSize); - return virtData->offset; - }, - .read = [](void *ptr, const sf_count_t count, void *user_data) -> sf_count_t { - auto* virtData = static_cast(user_data); - - const auto bytesToRead = std::min(virtData->dataSize - virtData->offset, count); - - memcpy(ptr, virtData->data + virtData->offset, bytesToRead); - virtData->offset += bytesToRead; - - return bytesToRead; - }, - .write = [](const void *ptr, const sf_count_t count, void *user_data) -> sf_count_t { - auto* virtData = static_cast(user_data); - - const auto bytesToWrite = std::min(virtData->dataSize - virtData->offset, count); - - memcpy(virtData->data + virtData->offset, ptr, bytesToWrite); - virtData->offset += bytesToWrite; - - return bytesToWrite; - }, - .tell = [](void *user_data) -> sf_count_t { - const auto* virtData = static_cast(user_data); - return virtData->offset; - }, -}; - -inline SF_VIRTUAL_IO g_VirtSndFileIO { - .get_filelen = [](void *user_data) -> sf_count_t { - const auto* virtData = static_cast(user_data); - return static_cast(virtData->data.size()); - }, - .seek = [](const sf_count_t offset, const int whence, void *user_data) -> sf_count_t { - auto* virtData = static_cast(user_data); - - switch (whence) - { - case SEEK_SET: - virtData->offset = offset; - break; - - case SEEK_CUR: - virtData->offset += offset; - break; - - case SEEK_END: - virtData->offset = virtData->data.size() + offset; - break; - - default: - break; - } - - assert(static_cast(virtData->offset) <= virtData->data.size()); - return virtData->offset; - }, - .read = [](void *ptr, const sf_count_t count, void *user_data) -> sf_count_t { - auto* virtData = static_cast(user_data); - - const auto bytesToRead = std::min(static_cast(virtData->data.size()) - virtData->offset, count); - - memcpy(ptr, virtData->data.data() + virtData->offset, bytesToRead); - virtData->offset += bytesToRead; - - return bytesToRead; - }, - .write = [](const void *ptr, const sf_count_t count, void *user_data) -> sf_count_t { - auto* virtData = static_cast(user_data); - - if (static_cast(virtData->data.size()) - virtData->offset < count) - virtData->data.resize(virtData->data.size() + count, 0); - - memcpy(virtData->data.data() + virtData->offset, ptr, count); - virtData->offset += count; - - return count; - }, - .tell = [](void *user_data) -> sf_count_t { - const auto* virtData = static_cast(user_data); - return virtData->offset; - }, -}; - -template , typename AllocatorType = std::allocator>> -using OrderedMap = std::map; - -template , typename AllocatorType = std::allocator> -using OrderedSet = std::set; - -template -using OptionalReference = std::optional>; - -#include "Singleton.hpp" -#include "UTF/UTF.hpp" - -using namespace UTF; - -#include "Options.hpp" -#include "Utils.hpp" diff --git a/src/Utils.hpp b/src/Utils.hpp deleted file mode 100644 index 1778c3c..0000000 --- a/src/Utils.hpp +++ /dev/null @@ -1,70 +0,0 @@ -// -// Created by Andrej Redeky. -// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. -// SPDX-License-Identifier: EUPL-1.2 -// - -#pragma once - -struct RIFFHeaderPCM -{ - char riffId[4] = {'R', 'I', 'F', 'F'}; - uint32_t riffSize = 0x24; - char waveId[4] = {'W', 'A', 'V', 'E'}; - char fmtId[4] = {'f', 'm', 't', ' '}; - uint32_t fmtSize = 0x10; - uint16_t fmtFormat = 1; - uint16_t fmtChannels = 0; - uint32_t fmtSampleRate = 0; - uint32_t fmtAvgBytesRate = 0; - uint16_t fmtBlockAlign = 0; - uint16_t fmtBitsPerSample = 0; - char dataId[4] = {'d', 'a', 't', 'a'}; - uint32_t dataSize = 0; -}; - -struct RIFFHeaderADPCM -{ - char riffId[4] = {'R', 'I', 'F', 'F'}; - uint32_t riffSize = 0x34; - char waveId[4] = {'W', 'A', 'V', 'E'}; - char fmtId[4] = {'f', 'm', 't', ' '}; - uint32_t fmtSize = 0x14; - uint16_t fmtFormat = 17; - uint16_t fmtChannels = 0; - uint32_t fmtSampleRate = 0; - uint32_t fmtAvgBytesRate = 0; - uint16_t fmtBlockAlign = 0; - uint16_t fmtBitsPerSample = 0; - uint16_t fmtExtraSize = 0x02; - uint16_t fmtExtra = 1017; - char factId[4] = {'f', 'a', 'c', 't'}; - uint32_t factSize = 0x04; - uint32_t factSamplesCount = 0; - char dataId[4] = {'d', 'a', 't', 'a'}; - uint32_t dataSize = 0; -}; - -std::vector ReadWholeBinaryFile(const StringView8CI &acpPath); - -String8 ReadWholeTextFile(const StringView8CI &acpPath); - -float GetAlignedItemWidth(int64_t acItemsCount); - -String8CI BrowseDirectoryDialog(); - -String8CI OpenFileDialog(const StringView8CI &filters, const StringView8CI &defaultFileName); - -String8CI SaveFileDialog(const StringView8CI &filters, const StringView8CI &defaultFileName); - -std::vector GetAllFilesInDirectory(const StringView8CI &directory, const StringView8CI &extension, bool recursive); - -StringView8CI GetProgramPath(); - -int32_t DisplayError(const StringView8 &message, const StringView8 &title = LocalizationManager::Get().Localize("MESSAGEBOX_ERROR_GENERIC_TITLE"), bool yesNo = false); - -int32_t DisplayWarning(const StringView8 &message, const StringView8 &title = LocalizationManager::Get().Localize("MESSAGEBOX_WARNING_GENERIC_TITLE"), bool yesNo = false, const Options &options = Options::Get()); - -std::vector GetPathStems(StringView8CI pathView); - -String8CI ChangeExtension(const StringView8CI &path, const StringView8CI &newExtension); diff --git a/src/backends/imgui_impl_opengl3.cpp b/src/backends/imgui_impl_opengl3.cpp deleted file mode 100644 index c9a0181..0000000 --- a/src/backends/imgui_impl_opengl3.cpp +++ /dev/null @@ -1,1083 +0,0 @@ -// dear imgui: Renderer Backend for modern OpenGL with shaders / programmatic pipeline -// - Desktop GL: 2.x 3.x 4.x -// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0) -// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..) - -// Implemented features: -// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about -// ImTextureID! [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices (Desktop OpenGL only). [X] -// Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= -// ImGuiConfigFlags_ViewportsEnable'. - -// About WebGL/ES: -// - You need to '#define IMGUI_IMPL_OPENGL_ES2' or '#define IMGUI_IMPL_OPENGL_ES3' to use WebGL or OpenGL ES. -// - This is done automatically on iOS, Android and Emscripten targets. -// - For other targets, the define needs to be visible from the imgui_impl_opengl3.cpp compilation unit. If unsure, -// define globally or in imconfig.h. - -// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. -// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build -// the backends you need. If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of -// imgui.cpp. Read online: https://github.com/ocornut/imgui/tree/master/docs - -// CHANGELOG -// (minor and older changes stripped away, please see git history for details) -// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. -// 2023-05-09: OpenGL: Support for glBindSampler() backup/restore on ES3. (#6375) -// 2023-04-18: OpenGL: Restore front and back polygon mode separately when supported by context. (#6333) -// 2023-03-23: OpenGL: Properly restoring "no shader program bound" if it was the case prior to running the rendering -// function. (#6267, #6220, #6224) 2023-03-15: OpenGL: Fixed GL loader crash when GL_VERSION returns NULL. (#6154, -// #4445, #3530) 2023-03-06: OpenGL: Fixed restoration of a potentially deleted OpenGL program, by calling -// glIsProgram(). (#6220, #6224) 2022-11-09: OpenGL: Reverted use of glBufferSubData(), too many corruptions issues + -// old issues seemingly can't be reproed with Intel drivers nowadays (revert 2021-12-15 and 2022-05-23 changes). -// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. -// 2022-09-27: OpenGL: Added ability to '#define IMGUI_IMPL_OPENGL_DEBUG'. -// 2022-05-23: OpenGL: Reworking 2021-12-15 "Using buffer orphaning" so it only happens on Intel GPU, seems to cause -// problems otherwise. (#4468, #4825, #4832, #5127). 2022-05-13: OpenGL: Fixed state corruption on OpenGL ES 2.0 due to -// not preserving GL_ELEMENT_ARRAY_BUFFER_BINDING and vertex attribute states. 2021-12-15: OpenGL: Using buffer -// orphaning + glBufferSubData(), seems to fix leaks with multi-viewports with some Intel HD drivers. 2021-08-23: -// OpenGL: Fixed ES 3.0 shader ("#version 300 es") use normal precision floats to avoid wobbly rendering at HD -// resolutions. 2021-08-19: OpenGL: Embed and use our own minimal GL loader (imgui_impl_opengl3_loader.h), removing -// requirement and support for third-party loader. 2021-06-29: Reorganized backend to pull data from a single structure -// to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). 2021-06-25: OpenGL: Use -// OES_vertex_array extension on Emscripten + backup/restore current state. 2021-06-21: OpenGL: Destroy individual -// vertex/fragment shader objects right after they are linked into the main shader. 2021-05-24: OpenGL: Access -// GL_CLIP_ORIGIN when "GL_ARB_clip_control" extension is detected, inside of just OpenGL 4.5 version. 2021-05-19: -// OpenGL: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a -// requirement) 2021-04-06: OpenGL: Don't try to read GL_CLIP_ORIGIN unless we're OpenGL 4.5 or greater. 2021-02-18: -// OpenGL: Change blending equation to preserve alpha in output buffer. 2021-01-03: OpenGL: Backup, setup and restore -// GL_STENCIL_TEST state. 2020-10-23: OpenGL: Backup, setup and restore GL_PRIMITIVE_RESTART state. 2020-10-15: OpenGL: -// Use glGetString(GL_VERSION) instead of glGetIntegerv(GL_MAJOR_VERSION, ...) when the later returns zero (e.g. -// Desktop GL 2.x) 2020-09-17: OpenGL: Fix to avoid compiling/calling glBindSampler() on ES or pre 3.3 context which -// have the defines set by a loader. 2020-07-10: OpenGL: Added support for glad2 OpenGL loader. 2020-05-08: OpenGL: -// Made default GLSL version 150 (instead of 130) on OSX. 2020-04-21: OpenGL: Fixed handling of -// glClipControl(GL_UPPER_LEFT) by inverting projection matrix. 2020-04-12: OpenGL: Fixed context version check -// mistakenly testing for 4.0+ instead of 3.2+ to enable ImGuiBackendFlags_RendererHasVtxOffset. 2020-03-24: OpenGL: -// Added support for glbinding 2.x OpenGL loader. 2020-01-07: OpenGL: Added support for glbinding 3.x OpenGL loader. -// 2019-10-25: OpenGL: Using a combination of GL define and runtime GL version to decide whether to use -// glDrawElementsBaseVertex(). Fix building with pre-3.2 GL loaders. 2019-09-22: OpenGL: Detect default GL loader using -// __has_include compiler facility. 2019-09-16: OpenGL: Tweak initialization code to allow application calling -// ImGui_ImplOpenGL3_CreateFontsTexture() before the first NewFrame() call. 2019-05-29: OpenGL: Desktop GL only: Added -// support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. 2019-04-30: OpenGL: -// Added support for special ImDrawCallback_ResetRenderState callback to reset render state. 2019-03-29: OpenGL: Not -// calling glBindBuffer more than necessary in the render loop. 2019-03-15: OpenGL: Added a GL call + comments in -// ImGui_ImplOpenGL3_Init() to detect uninitialized GL function loaders early. 2019-03-03: OpenGL: Fix support for -// ES 2.0 (WebGL 1.0). 2019-02-20: OpenGL: Fix for OSX not supporting OpenGL 4.5, we don't try to read GL_CLIP_ORIGIN -// even if defined by the headers/loader. 2019-02-11: OpenGL: Projecting clipping rectangles correctly using -// draw_data->FramebufferScale to allow multi-viewports for retina display. 2019-02-01: OpenGL: Using GLSL 410 shaders -// for any version over 410 (e.g. 430, 450). 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed -// in the About Window. 2018-11-13: OpenGL: Support for GL 4.5's glClipControl(GL_UPPER_LEFT) / GL_CLIP_ORIGIN. -// 2018-08-29: OpenGL: Added support for more OpenGL loaders: glew and glad, with comments indicative that any loader -// can be used. 2018-08-09: OpenGL: Default to OpenGL ES 3 on iOS and Android. GLSL version default to "#version 300 -// ES". 2018-07-30: OpenGL: Support for GLSL 300 ES and 410 core. Fixes for Emscripten compilation. 2018-07-10: OpenGL: -// Support for more GLSL versions (based on the GLSL version string). Added error output when shaders fail to -// compile/link. 2018-06-08: Misc: Extracted imgui_impl_opengl3.cpp/.h away from the old combined GLFW/SDL+OpenGL3 -// examples. 2018-06-08: OpenGL: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and -// clipping rectangle. 2018-05-25: OpenGL: Removed unnecessary backup/restore of GL_ELEMENT_ARRAY_BUFFER_BINDING since -// this is part of the VAO state. 2018-05-14: OpenGL: Making the call to glBindSampler() optional so 3.2 context won't -// fail if the function is a nullptr pointer. 2018-03-06: OpenGL: Added const char* glsl_version parameter to -// ImGui_ImplOpenGL3_Init() so user can override the GLSL version e.g. "#version 150". 2018-02-23: OpenGL: Create the -// VAO in the render function so the setup can more easily be used with multiple shared GL context. 2018-02-16: Misc: -// Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplSdlGL3_RenderDrawData() in the .h file so you can -// call it yourself. 2018-01-07: OpenGL: Changed GLSL shader version from 330 to 150. 2017-09-01: OpenGL: Save and -// restore current bound sampler. Save and restore current polygon mode. 2017-05-01: OpenGL: Fixed save and restore of -// current blend func state. 2017-05-01: OpenGL: Fixed save and restore of current GL_ACTIVE_TEXTURE. 2016-09-05: -// OpenGL: Fixed save and restore of current scissor rectangle. 2016-07-29: OpenGL: Explicitly setting -// GL_UNPACK_ROW_LENGTH to reduce issues because SDL changes it. (#752) - -//---------------------------------------- -// OpenGL GLSL GLSL -// version version string -//---------------------------------------- -// 2.0 110 "#version 110" -// 2.1 120 "#version 120" -// 3.0 130 "#version 130" -// 3.1 140 "#version 140" -// 3.2 150 "#version 150" -// 3.3 330 "#version 330 core" -// 4.0 400 "#version 400 core" -// 4.1 410 "#version 410 core" -// 4.2 420 "#version 410 core" -// 4.3 430 "#version 430 core" -// ES 2.0 100 "#version 100" = WebGL 1.0 -// ES 3.0 300 "#version 300 es" = WebGL 2.0 -//---------------------------------------- - -#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) -# define _CRT_SECURE_NO_WARNINGS -#endif - -#include "imgui_impl_opengl3.h" -#include "imgui.h" -#include -#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier -# include // intptr_t -#else -# include // intptr_t -#endif -#if defined(__APPLE__) -# include -#endif - -// Clang/GCC warnings with -Weverything -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast -# pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness -# pragma clang diagnostic ignored "-Wunused-macros" // warning: macro is not used -# pragma clang diagnostic ignored "-Wnonportable-system-include-path" -# pragma clang diagnostic ignored \ - "-Wcast-function-type" // warning: cast between incompatible function types (for loader) -#endif -#if defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind -# pragma GCC diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' -# pragma GCC diagnostic ignored \ - "-Wcast-function-type" // warning: cast between incompatible function types (for loader) -#endif - -// GL includes -#if defined(IMGUI_IMPL_OPENGL_ES2) -# if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) -# include // Use GL ES 2 -# else -# include // Use GL ES 2 -# endif -# if defined(__EMSCRIPTEN__) -# ifndef GL_GLEXT_PROTOTYPES -# define GL_GLEXT_PROTOTYPES -# endif -# include -# endif -#elif defined(IMGUI_IMPL_OPENGL_ES3) -# if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) -# include // Use GL ES 3 -# else -# include // Use GL ES 3 -# endif -#elif !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM) -// Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers. -// Helper libraries are often used for this purpose! Here we are using our own minimal custom loader based on gl3w. -// In the rest of your app/engine, you can use another loader of your choice (gl3w, glew, glad, glbinding, glext, -// glLoadGen, etc.). If you happen to be developing a new feature for this backend (imgui_impl_opengl3.cpp): -// - You may need to regenerate imgui_impl_opengl3_loader.h to add new symbols. See -// https://github.com/dearimgui/gl3w_stripped -// - You can temporarily use an unstripped version. See https://github.com/dearimgui/gl3w_stripped/releases -// Changes to this backend using new APIs should be accompanied by a regenerated stripped loader version. -# define IMGL3W_IMPL -# include "imgui_impl_opengl3_loader.h" -#endif - -// Vertex arrays are not supported on ES2/WebGL1 unless Emscripten which uses an extension -#ifndef IMGUI_IMPL_OPENGL_ES2 -# define IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY -#elif defined(__EMSCRIPTEN__) -# define IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY -# define glBindVertexArray glBindVertexArrayOES -# define glGenVertexArrays glGenVertexArraysOES -# define glDeleteVertexArrays glDeleteVertexArraysOES -# define GL_VERTEX_ARRAY_BINDING GL_VERTEX_ARRAY_BINDING_OES -#endif - -// Desktop GL 2.0+ has glPolygonMode() which GL ES and WebGL don't have. -#ifdef GL_POLYGON_MODE -# define IMGUI_IMPL_HAS_POLYGON_MODE -#endif - -// Desktop GL 3.2+ has glDrawElementsBaseVertex() which GL ES and WebGL don't have. -#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && defined(GL_VERSION_3_2) -# define IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET -#endif - -// Desktop GL 3.3+ and GL ES 3.0+ have glBindSampler() -#if !defined(IMGUI_IMPL_OPENGL_ES2) && (defined(IMGUI_IMPL_OPENGL_ES3) || defined(GL_VERSION_3_3)) -# define IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER -#endif - -// Desktop GL 3.1+ has GL_PRIMITIVE_RESTART state -#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && defined(GL_VERSION_3_1) -# define IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART -#endif - -// Desktop GL use extension detection -#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) -# define IMGUI_IMPL_OPENGL_MAY_HAVE_EXTENSIONS -#endif - -// [Debugging] -// #define IMGUI_IMPL_OPENGL_DEBUG -#ifdef IMGUI_IMPL_OPENGL_DEBUG -# include -# define GL_CALL(_CALL) \ - do \ - { \ - _CALL; \ - GLenum gl_err = glGetError(); \ - if (gl_err != 0) \ - fprintf(stderr, "GL error 0x%x returned from '%s'.\n", gl_err, #_CALL); \ - } while (0) // Call with error check -#else -# define GL_CALL(_CALL) _CALL // Call without error check -#endif - -// OpenGL Data -struct ImGui_ImplOpenGL3_Data -{ - GLuint GlVersion; // Extracted at runtime using GL_MAJOR_VERSION, GL_MINOR_VERSION queries (e.g. 320 for GL 3.2) - char GlslVersionString[32]; // Specified by user or detected based on compile time GL settings. - bool GlProfileIsES2; - bool GlProfileIsES3; - bool GlProfileIsCompat; - GLint GlProfileMask; - GLuint FontTexture; - GLuint ShaderHandle; - GLint AttribLocationTex; // Uniforms location - GLint AttribLocationProjMtx; - GLuint AttribLocationVtxPos; // Vertex attributes location - GLuint AttribLocationVtxUV; - GLuint AttribLocationVtxColor; - unsigned int VboHandle, ElementsHandle; - GLsizeiptr VertexBufferSize; - GLsizeiptr IndexBufferSize; - bool HasClipOrigin; - bool UseBufferSubData; - - ImGui_ImplOpenGL3_Data() - { - memset((void *)this, 0, sizeof(*this)); - } -}; - -// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts -// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple -// windows) instead of multiple Dear ImGui contexts. -static ImGui_ImplOpenGL3_Data *ImGui_ImplOpenGL3_GetBackendData() -{ - return ImGui::GetCurrentContext() ? (ImGui_ImplOpenGL3_Data *)ImGui::GetIO().BackendRendererUserData : nullptr; -} - -// Forward Declarations -static void ImGui_ImplOpenGL3_InitPlatformInterface(); -static void ImGui_ImplOpenGL3_ShutdownPlatformInterface(); - -// OpenGL vertex attribute state (for ES 1.0 and ES 2.0 only) -#ifndef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY -struct ImGui_ImplOpenGL3_VtxAttribState -{ - GLint Enabled, Size, Type, Normalized, Stride; - GLvoid *Ptr; - - void GetState(GLint index) - { - glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &Enabled); - glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_SIZE, &Size); - glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_TYPE, &Type); - glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &Normalized); - glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &Stride); - glGetVertexAttribPointerv(index, GL_VERTEX_ATTRIB_ARRAY_POINTER, &Ptr); - } - void SetState(GLint index) - { - glVertexAttribPointer(index, Size, Type, (GLboolean)Normalized, Stride, Ptr); - if (Enabled) - glEnableVertexAttribArray(index); - else - glDisableVertexAttribArray(index); - } -}; -#endif - -// Functions -bool ImGui_ImplOpenGL3_Init(const char *glsl_version) -{ - ImGuiIO &io = ImGui::GetIO(); - IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); - - // Initialize our loader -#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM) - if (imgl3wInit() != 0) - { - fprintf(stderr, "Failed to initialize OpenGL loader!\n"); - return false; - } -#endif - - // Setup backend capabilities flags - ImGui_ImplOpenGL3_Data *bd = IM_NEW(ImGui_ImplOpenGL3_Data)(); - io.BackendRendererUserData = (void *)bd; - io.BackendRendererName = "imgui_impl_opengl3"; - - // Query for GL version (e.g. 320 for GL 3.2) -#if !defined(IMGUI_IMPL_OPENGL_ES2) - GLint major = 0; - GLint minor = 0; - glGetIntegerv(GL_MAJOR_VERSION, &major); - glGetIntegerv(GL_MINOR_VERSION, &minor); - if (major == 0 && minor == 0) - { - // Query GL_VERSION in desktop GL 2.x, the string will start with "." - const char *gl_version = (const char *)glGetString(GL_VERSION); - sscanf(gl_version, "%d.%d", &major, &minor); - } - bd->GlVersion = (GLuint)(major * 100 + minor * 10); -# if defined(GL_CONTEXT_PROFILE_MASK) - glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &bd->GlProfileMask); - bd->GlProfileIsCompat = (bd->GlProfileMask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) != 0; -# endif - - bd->UseBufferSubData = false; - /* - // Query vendor to enable glBufferSubData kludge -#ifdef _WIN32 - if (const char* vendor = (const char*)glGetString(GL_VENDOR)) - if (strncmp(vendor, "Intel", 5) == 0) - bd->UseBufferSubData = true; -#endif - */ -#elif defined(IMGUI_IMPL_OPENGL_ES2) - bd->GlVersion = 200; // GLES 2 - bd->GlProfileIsES2 = true; -#elif defined(IMGUI_IMPL_OPENGL_ES3) - bd->GlVersion = 200; // Don't raise version as it is intended as a desktop version check for now. - bd->GlProfileIsES3 = true; -#endif - -#ifdef IMGUI_IMPL_OPENGL_DEBUG - printf("GL_MAJOR_VERSION = %d\nGL_MINOR_VERSION = %d\nGL_VENDOR = '%s'\nGL_RENDERER = '%s'\n", major, minor, - (const char *)glGetString(GL_VENDOR), (const char *)glGetString(GL_RENDERER)); // [DEBUG] -#endif - -#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET - if (bd->GlVersion >= 320) - io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing - // for large meshes. -#endif - io.BackendFlags |= - ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional) - - // Store GLSL version string so we can refer to it later in case we recreate shaders. - // Note: GLSL version is NOT the same as GL version. Leave this to nullptr if unsure. - if (glsl_version == nullptr) - { -#if defined(IMGUI_IMPL_OPENGL_ES2) - glsl_version = "#version 100"; -#elif defined(IMGUI_IMPL_OPENGL_ES3) - glsl_version = "#version 300 es"; -#elif defined(__APPLE__) - glsl_version = "#version 150"; -#else - glsl_version = "#version 130"; -#endif - } - IM_ASSERT((int)strlen(glsl_version) + 2 < IM_ARRAYSIZE(bd->GlslVersionString)); - strcpy(bd->GlslVersionString, glsl_version); - strcat(bd->GlslVersionString, "\n"); - - // Make an arbitrary GL call (we don't actually need the result) - // IF YOU GET A CRASH HERE: it probably means the OpenGL function loader didn't do its job. Let us know! - GLint current_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture); - - // Detect extensions we support - bd->HasClipOrigin = (bd->GlVersion >= 450); -#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_EXTENSIONS - GLint num_extensions = 0; - glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions); - for (GLint i = 0; i < num_extensions; i++) - { - const char *extension = (const char *)glGetStringi(GL_EXTENSIONS, i); - if (extension != nullptr && strcmp(extension, "GL_ARB_clip_control") == 0) - bd->HasClipOrigin = true; - } -#endif - - if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) - ImGui_ImplOpenGL3_InitPlatformInterface(); - - return true; -} - -void ImGui_ImplOpenGL3_Shutdown() -{ - ImGui_ImplOpenGL3_Data *bd = ImGui_ImplOpenGL3_GetBackendData(); - IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?"); - ImGuiIO &io = ImGui::GetIO(); - - ImGui_ImplOpenGL3_ShutdownPlatformInterface(); - ImGui_ImplOpenGL3_DestroyDeviceObjects(); - io.BackendRendererName = nullptr; - io.BackendRendererUserData = nullptr; - io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasViewports); - IM_DELETE(bd); -} - -void ImGui_ImplOpenGL3_NewFrame() -{ - ImGui_ImplOpenGL3_Data *bd = ImGui_ImplOpenGL3_GetBackendData(); - IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplOpenGL3_Init()?"); - - if (!bd->ShaderHandle) - ImGui_ImplOpenGL3_CreateDeviceObjects(); -} - -static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData *draw_data, int fb_width, int fb_height, - GLuint vertex_array_object) -{ - ImGui_ImplOpenGL3_Data *bd = ImGui_ImplOpenGL3_GetBackendData(); - - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill - glEnable(GL_BLEND); - glBlendEquation(GL_FUNC_ADD); - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glDisable(GL_STENCIL_TEST); - glEnable(GL_SCISSOR_TEST); -#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART - if (bd->GlVersion >= 310) - glDisable(GL_PRIMITIVE_RESTART); -#endif -#ifdef IMGUI_IMPL_HAS_POLYGON_MODE - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); -#endif - - // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT) -#if defined(GL_CLIP_ORIGIN) - bool clip_origin_lower_left = true; - if (bd->HasClipOrigin) - { - GLenum current_clip_origin = 0; - glGetIntegerv(GL_CLIP_ORIGIN, (GLint *)¤t_clip_origin); - if (current_clip_origin == GL_UPPER_LEFT) - clip_origin_lower_left = false; - } -#endif - - // Setup viewport, orthographic projection matrix - // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize - // (bottom right). DisplayPos is (0,0) for single viewport apps. - GL_CALL(glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height)); - float L = draw_data->DisplayPos.x; - float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; - float T = draw_data->DisplayPos.y; - float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; -#if defined(GL_CLIP_ORIGIN) - if (!clip_origin_lower_left) - { - float tmp = T; - T = B; - B = tmp; - } // Swap top and bottom if origin is upper left -#endif - const float ortho_projection[4][4] = { - {2.0f / (R - L), 0.0f, 0.0f, 0.0f}, - {0.0f, 2.0f / (T - B), 0.0f, 0.0f}, - {0.0f, 0.0f, -1.0f, 0.0f}, - {(R + L) / (L - R), (T + B) / (B - T), 0.0f, 1.0f}, - }; - glUseProgram(bd->ShaderHandle); - glUniform1i(bd->AttribLocationTex, 0); - glUniformMatrix4fv(bd->AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); - -#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER - if (bd->GlVersion >= 330 || bd->GlProfileIsES3) - glBindSampler( - 0, 0); // We use combined texture/sampler state. Applications using GL 3.3 and GL ES 3.0 may set that otherwise. -#endif - - (void)vertex_array_object; -#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY - glBindVertexArray(vertex_array_object); -#endif - - // Bind vertex/index buffers and setup attributes for ImDrawVert - GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, bd->VboHandle)); - GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bd->ElementsHandle)); - GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxPos)); - GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxUV)); - GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxColor)); - GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), - (GLvoid *)IM_OFFSETOF(ImDrawVert, pos))); - GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), - (GLvoid *)IM_OFFSETOF(ImDrawVert, uv))); - GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), - (GLvoid *)IM_OFFSETOF(ImDrawVert, col))); -} - -// OpenGL3 Render function. -// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state -// explicitly. This is in order to be able to run within an OpenGL engine that doesn't do so. -void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData *draw_data) -{ - // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer - // coordinates) - int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x); - int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); - if (fb_width <= 0 || fb_height <= 0) - return; - - ImGui_ImplOpenGL3_Data *bd = ImGui_ImplOpenGL3_GetBackendData(); - - // Backup GL state - GLenum last_active_texture; - glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint *)&last_active_texture); - glActiveTexture(GL_TEXTURE0); - GLuint last_program; - glGetIntegerv(GL_CURRENT_PROGRAM, (GLint *)&last_program); - GLuint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint *)&last_texture); -#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER - GLuint last_sampler; - if (bd->GlVersion >= 330 || bd->GlProfileIsES3) - { - glGetIntegerv(GL_SAMPLER_BINDING, (GLint *)&last_sampler); - } - else - { - last_sampler = 0; - } -#endif - GLuint last_array_buffer; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint *)&last_array_buffer); -#ifndef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY - // This is part of VAO on OpenGL 3.0+ and OpenGL ES 3.0+. - GLint last_element_array_buffer; - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); - ImGui_ImplOpenGL3_VtxAttribState last_vtx_attrib_state_pos; - last_vtx_attrib_state_pos.GetState(bd->AttribLocationVtxPos); - ImGui_ImplOpenGL3_VtxAttribState last_vtx_attrib_state_uv; - last_vtx_attrib_state_uv.GetState(bd->AttribLocationVtxUV); - ImGui_ImplOpenGL3_VtxAttribState last_vtx_attrib_state_color; - last_vtx_attrib_state_color.GetState(bd->AttribLocationVtxColor); -#endif -#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY - GLuint last_vertex_array_object; - glGetIntegerv(GL_VERTEX_ARRAY_BINDING, (GLint *)&last_vertex_array_object); -#endif -#ifdef IMGUI_IMPL_HAS_POLYGON_MODE - GLint last_polygon_mode[2]; - glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); -#endif - GLint last_viewport[4]; - glGetIntegerv(GL_VIEWPORT, last_viewport); - GLint last_scissor_box[4]; - glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); - GLenum last_blend_src_rgb; - glGetIntegerv(GL_BLEND_SRC_RGB, (GLint *)&last_blend_src_rgb); - GLenum last_blend_dst_rgb; - glGetIntegerv(GL_BLEND_DST_RGB, (GLint *)&last_blend_dst_rgb); - GLenum last_blend_src_alpha; - glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint *)&last_blend_src_alpha); - GLenum last_blend_dst_alpha; - glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint *)&last_blend_dst_alpha); - GLenum last_blend_equation_rgb; - glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint *)&last_blend_equation_rgb); - GLenum last_blend_equation_alpha; - glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint *)&last_blend_equation_alpha); - GLboolean last_enable_blend = glIsEnabled(GL_BLEND); - GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); - GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); - GLboolean last_enable_stencil_test = glIsEnabled(GL_STENCIL_TEST); - GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); -#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART - GLboolean last_enable_primitive_restart = (bd->GlVersion >= 310) ? glIsEnabled(GL_PRIMITIVE_RESTART) : GL_FALSE; -#endif - - // Setup desired GL state - // Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. VAO are not shared - // among GL contexts) The renderer would actually work without any VAO bound, but then our VertexAttrib calls would - // overwrite the default one currently bound. - GLuint vertex_array_object = 0; -#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY - GL_CALL(glGenVertexArrays(1, &vertex_array_object)); -#endif - ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object); - - // Will project scissor/clipping rectangles into framebuffer space - ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports - ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2) - - // Render command lists - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList *cmd_list = draw_data->CmdLists[n]; - - // Upload vertex/index buffers - // - OpenGL drivers are in a very sorry state nowadays.... - // During 2021 we attempted to switch from glBufferData() to orphaning+glBufferSubData() following reports - // of leaks on Intel GPU when using multi-viewports on Windows. - // - After this we kept hearing of various display corruptions issues. We started disabling on non-Intel GPU, but - // issues still got reported on Intel. - // - We are now back to using exclusively glBufferData(). So bd->UseBufferSubData IS ALWAYS FALSE in this code. - // We are keeping the old code path for a while in case people finding new issues may want to test the - // bd->UseBufferSubData path. - // - See https://github.com/ocornut/imgui/issues/4468 and please report any corruption issues. - const GLsizeiptr vtx_buffer_size = (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert); - const GLsizeiptr idx_buffer_size = (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx); - if (bd->UseBufferSubData) - { - if (bd->VertexBufferSize < vtx_buffer_size) - { - bd->VertexBufferSize = vtx_buffer_size; - GL_CALL(glBufferData(GL_ARRAY_BUFFER, bd->VertexBufferSize, nullptr, GL_STREAM_DRAW)); - } - if (bd->IndexBufferSize < idx_buffer_size) - { - bd->IndexBufferSize = idx_buffer_size; - GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, bd->IndexBufferSize, nullptr, GL_STREAM_DRAW)); - } - GL_CALL(glBufferSubData(GL_ARRAY_BUFFER, 0, vtx_buffer_size, (const GLvoid *)cmd_list->VtxBuffer.Data)); - GL_CALL(glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, idx_buffer_size, (const GLvoid *)cmd_list->IdxBuffer.Data)); - } - else - { - GL_CALL(glBufferData(GL_ARRAY_BUFFER, vtx_buffer_size, (const GLvoid *)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW)); - GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size, (const GLvoid *)cmd_list->IdxBuffer.Data, - GL_STREAM_DRAW)); - } - - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) - { - const ImDrawCmd *pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->UserCallback != nullptr) - { - // User callback, registered via ImDrawList::AddCallback() - // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to - // reset render state.) - if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) - ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object); - else - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - // Project scissor/clipping rectangles into framebuffer space - ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y); - ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y); - if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) - continue; - - // Apply scissor/clipping rectangle (Y is inverted in OpenGL) - GL_CALL(glScissor((int)clip_min.x, (int)((float)fb_height - clip_max.y), (int)(clip_max.x - clip_min.x), - (int)(clip_max.y - clip_min.y))); - - // Bind texture, Draw - GL_CALL(glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID())); -#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET - if (bd->GlVersion >= 320) - GL_CALL(glDrawElementsBaseVertex( - GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, - (void *)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)), (GLint)pcmd->VtxOffset)); - else -#endif - GL_CALL(glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, - sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, - (void *)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)))); - } - } - } - - // Destroy the temporary VAO -#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY - GL_CALL(glDeleteVertexArrays(1, &vertex_array_object)); -#endif - - // Restore modified GL state - // This "glIsProgram()" check is required because if the program is "pending deletion" at the time of binding backup, - // it will have been deleted by now and will cause an OpenGL error. See #6220. - if (last_program == 0 || glIsProgram(last_program)) - glUseProgram(last_program); - glBindTexture(GL_TEXTURE_2D, last_texture); -#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER - if (bd->GlVersion >= 330 || bd->GlProfileIsES3) - glBindSampler(0, last_sampler); -#endif - glActiveTexture(last_active_texture); -#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY - glBindVertexArray(last_vertex_array_object); -#endif - glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); -#ifndef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer); - last_vtx_attrib_state_pos.SetState(bd->AttribLocationVtxPos); - last_vtx_attrib_state_uv.SetState(bd->AttribLocationVtxUV); - last_vtx_attrib_state_color.SetState(bd->AttribLocationVtxColor); -#endif - glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); - glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha); - if (last_enable_blend) - glEnable(GL_BLEND); - else - glDisable(GL_BLEND); - if (last_enable_cull_face) - glEnable(GL_CULL_FACE); - else - glDisable(GL_CULL_FACE); - if (last_enable_depth_test) - glEnable(GL_DEPTH_TEST); - else - glDisable(GL_DEPTH_TEST); - if (last_enable_stencil_test) - glEnable(GL_STENCIL_TEST); - else - glDisable(GL_STENCIL_TEST); - if (last_enable_scissor_test) - glEnable(GL_SCISSOR_TEST); - else - glDisable(GL_SCISSOR_TEST); -#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART - if (bd->GlVersion >= 310) - { - if (last_enable_primitive_restart) - glEnable(GL_PRIMITIVE_RESTART); - else - glDisable(GL_PRIMITIVE_RESTART); - } -#endif - -#ifdef IMGUI_IMPL_HAS_POLYGON_MODE - // Desktop OpenGL 3.0 and OpenGL 3.1 had separate polygon draw modes for front-facing and back-facing faces of - // polygons - if (bd->GlVersion <= 310 || bd->GlProfileIsCompat) - { - glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); - glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]); - } - else - { - glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]); - } -#endif // IMGUI_IMPL_HAS_POLYGON_MODE - - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); - glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); - (void)bd; // Not all compilation paths use this -} - -bool ImGui_ImplOpenGL3_CreateFontsTexture() -{ - ImGuiIO &io = ImGui::GetIO(); - ImGui_ImplOpenGL3_Data *bd = ImGui_ImplOpenGL3_GetBackendData(); - - // Build texture atlas - unsigned char *pixels; - int width, height; - io.Fonts->GetTexDataAsRGBA32( - &pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) - // because it is more likely to be compatible with user's existing shaders. If your - // ImTextureId represent a higher-level concept than just a GL texture id, consider - // calling GetTexDataAsAlpha8() instead to save on GPU memory. - - // Upload texture to graphics system - // (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or - // 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling) - GLint last_texture; - GL_CALL(glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture)); - GL_CALL(glGenTextures(1, &bd->FontTexture)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, bd->FontTexture)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); -#ifdef GL_UNPACK_ROW_LENGTH // Not on WebGL/ES - GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)); -#endif - GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels)); - - // Store our identifier - io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontTexture); - - // Restore state - GL_CALL(glBindTexture(GL_TEXTURE_2D, last_texture)); - - return true; -} - -void ImGui_ImplOpenGL3_DestroyFontsTexture() -{ - ImGuiIO &io = ImGui::GetIO(); - ImGui_ImplOpenGL3_Data *bd = ImGui_ImplOpenGL3_GetBackendData(); - if (bd->FontTexture) - { - glDeleteTextures(1, &bd->FontTexture); - io.Fonts->SetTexID(0); - bd->FontTexture = 0; - } -} - -// If you get an error please report on github. You may try different GL context version or GLSL version. See GL<>GLSL -// version table at the top of this file. -static bool CheckShader(GLuint handle, const char *desc) -{ - ImGui_ImplOpenGL3_Data *bd = ImGui_ImplOpenGL3_GetBackendData(); - GLint status = 0, log_length = 0; - glGetShaderiv(handle, GL_COMPILE_STATUS, &status); - glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &log_length); - if ((GLboolean)status == GL_FALSE) - fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile %s! With GLSL: %s\n", desc, - bd->GlslVersionString); - if (log_length > 1) - { - ImVector buf; - buf.resize((int)(log_length + 1)); - glGetShaderInfoLog(handle, log_length, nullptr, (GLchar *)buf.begin()); - fprintf(stderr, "%s\n", buf.begin()); - } - return (GLboolean)status == GL_TRUE; -} - -// If you get an error please report on GitHub. You may try different GL context version or GLSL version. -static bool CheckProgram(GLuint handle, const char *desc) -{ - ImGui_ImplOpenGL3_Data *bd = ImGui_ImplOpenGL3_GetBackendData(); - GLint status = 0, log_length = 0; - glGetProgramiv(handle, GL_LINK_STATUS, &status); - glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &log_length); - if ((GLboolean)status == GL_FALSE) - fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to link %s! With GLSL %s\n", desc, - bd->GlslVersionString); - if (log_length > 1) - { - ImVector buf; - buf.resize((int)(log_length + 1)); - glGetProgramInfoLog(handle, log_length, nullptr, (GLchar *)buf.begin()); - fprintf(stderr, "%s\n", buf.begin()); - } - return (GLboolean)status == GL_TRUE; -} - -bool ImGui_ImplOpenGL3_CreateDeviceObjects() -{ - ImGui_ImplOpenGL3_Data *bd = ImGui_ImplOpenGL3_GetBackendData(); - - // Backup GL state - GLint last_texture, last_array_buffer; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); -#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY - GLint last_vertex_array; - glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); -#endif - - // Parse GLSL version string - int glsl_version = 130; - sscanf(bd->GlslVersionString, "#version %d", &glsl_version); - - const GLchar *vertex_shader_glsl_120 = "uniform mat4 ProjMtx;\n" - "attribute vec2 Position;\n" - "attribute vec2 UV;\n" - "attribute vec4 Color;\n" - "varying vec2 Frag_UV;\n" - "varying vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " Frag_UV = UV;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" - "}\n"; - - const GLchar *vertex_shader_glsl_130 = "uniform mat4 ProjMtx;\n" - "in vec2 Position;\n" - "in vec2 UV;\n" - "in vec4 Color;\n" - "out vec2 Frag_UV;\n" - "out vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " Frag_UV = UV;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" - "}\n"; - - const GLchar *vertex_shader_glsl_300_es = "precision highp float;\n" - "layout (location = 0) in vec2 Position;\n" - "layout (location = 1) in vec2 UV;\n" - "layout (location = 2) in vec4 Color;\n" - "uniform mat4 ProjMtx;\n" - "out vec2 Frag_UV;\n" - "out vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " Frag_UV = UV;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" - "}\n"; - - const GLchar *vertex_shader_glsl_410_core = "layout (location = 0) in vec2 Position;\n" - "layout (location = 1) in vec2 UV;\n" - "layout (location = 2) in vec4 Color;\n" - "uniform mat4 ProjMtx;\n" - "out vec2 Frag_UV;\n" - "out vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " Frag_UV = UV;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" - "}\n"; - - const GLchar *fragment_shader_glsl_120 = "#ifdef GL_ES\n" - " precision mediump float;\n" - "#endif\n" - "uniform sampler2D Texture;\n" - "varying vec2 Frag_UV;\n" - "varying vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n" - "}\n"; - - const GLchar *fragment_shader_glsl_130 = "uniform sampler2D Texture;\n" - "in vec2 Frag_UV;\n" - "in vec4 Frag_Color;\n" - "out vec4 Out_Color;\n" - "void main()\n" - "{\n" - " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" - "}\n"; - - const GLchar *fragment_shader_glsl_300_es = "precision mediump float;\n" - "uniform sampler2D Texture;\n" - "in vec2 Frag_UV;\n" - "in vec4 Frag_Color;\n" - "layout (location = 0) out vec4 Out_Color;\n" - "void main()\n" - "{\n" - " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" - "}\n"; - - const GLchar *fragment_shader_glsl_410_core = "in vec2 Frag_UV;\n" - "in vec4 Frag_Color;\n" - "uniform sampler2D Texture;\n" - "layout (location = 0) out vec4 Out_Color;\n" - "void main()\n" - "{\n" - " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" - "}\n"; - - // Select shaders matching our GLSL versions - const GLchar *vertex_shader = nullptr; - const GLchar *fragment_shader = nullptr; - if (glsl_version < 130) - { - vertex_shader = vertex_shader_glsl_120; - fragment_shader = fragment_shader_glsl_120; - } - else if (glsl_version >= 410) - { - vertex_shader = vertex_shader_glsl_410_core; - fragment_shader = fragment_shader_glsl_410_core; - } - else if (glsl_version == 300) - { - vertex_shader = vertex_shader_glsl_300_es; - fragment_shader = fragment_shader_glsl_300_es; - } - else - { - vertex_shader = vertex_shader_glsl_130; - fragment_shader = fragment_shader_glsl_130; - } - - // Create shaders - const GLchar *vertex_shader_with_version[2] = {bd->GlslVersionString, vertex_shader}; - GLuint vert_handle = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vert_handle, 2, vertex_shader_with_version, nullptr); - glCompileShader(vert_handle); - CheckShader(vert_handle, "vertex shader"); - - const GLchar *fragment_shader_with_version[2] = {bd->GlslVersionString, fragment_shader}; - GLuint frag_handle = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(frag_handle, 2, fragment_shader_with_version, nullptr); - glCompileShader(frag_handle); - CheckShader(frag_handle, "fragment shader"); - - // Link - bd->ShaderHandle = glCreateProgram(); - glAttachShader(bd->ShaderHandle, vert_handle); - glAttachShader(bd->ShaderHandle, frag_handle); - glLinkProgram(bd->ShaderHandle); - CheckProgram(bd->ShaderHandle, "shader program"); - - glDetachShader(bd->ShaderHandle, vert_handle); - glDetachShader(bd->ShaderHandle, frag_handle); - glDeleteShader(vert_handle); - glDeleteShader(frag_handle); - - bd->AttribLocationTex = glGetUniformLocation(bd->ShaderHandle, "Texture"); - bd->AttribLocationProjMtx = glGetUniformLocation(bd->ShaderHandle, "ProjMtx"); - bd->AttribLocationVtxPos = (GLuint)glGetAttribLocation(bd->ShaderHandle, "Position"); - bd->AttribLocationVtxUV = (GLuint)glGetAttribLocation(bd->ShaderHandle, "UV"); - bd->AttribLocationVtxColor = (GLuint)glGetAttribLocation(bd->ShaderHandle, "Color"); - - // Create buffers - glGenBuffers(1, &bd->VboHandle); - glGenBuffers(1, &bd->ElementsHandle); - - ImGui_ImplOpenGL3_CreateFontsTexture(); - - // Restore modified GL state - glBindTexture(GL_TEXTURE_2D, last_texture); - glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); -#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY - glBindVertexArray(last_vertex_array); -#endif - - return true; -} - -void ImGui_ImplOpenGL3_DestroyDeviceObjects() -{ - ImGui_ImplOpenGL3_Data *bd = ImGui_ImplOpenGL3_GetBackendData(); - if (bd->VboHandle) - { - glDeleteBuffers(1, &bd->VboHandle); - bd->VboHandle = 0; - } - if (bd->ElementsHandle) - { - glDeleteBuffers(1, &bd->ElementsHandle); - bd->ElementsHandle = 0; - } - if (bd->ShaderHandle) - { - glDeleteProgram(bd->ShaderHandle); - bd->ShaderHandle = 0; - } - ImGui_ImplOpenGL3_DestroyFontsTexture(); -} - -//-------------------------------------------------------------------------------------------------------- -// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT -// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports -// simultaneously. If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you -// completely ignore this section first.. -//-------------------------------------------------------------------------------------------------------- - -static void ImGui_ImplOpenGL3_RenderWindow(ImGuiViewport *viewport, void *) -{ - if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear)) - { - ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); - glClear(GL_COLOR_BUFFER_BIT); - } - ImGui_ImplOpenGL3_RenderDrawData(viewport->DrawData); -} - -static void ImGui_ImplOpenGL3_InitPlatformInterface() -{ - ImGuiPlatformIO &platform_io = ImGui::GetPlatformIO(); - platform_io.Renderer_RenderWindow = ImGui_ImplOpenGL3_RenderWindow; -} - -static void ImGui_ImplOpenGL3_ShutdownPlatformInterface() -{ - ImGui::DestroyPlatformWindows(); -} - -#if defined(__GNUC__) -# pragma GCC diagnostic pop -#endif -#if defined(__clang__) -# pragma clang diagnostic pop -#endif diff --git a/src/backends/imgui_impl_opengl3.h b/src/backends/imgui_impl_opengl3.h deleted file mode 100644 index ae65a61..0000000 --- a/src/backends/imgui_impl_opengl3.h +++ /dev/null @@ -1,64 +0,0 @@ -// dear imgui: Renderer Backend for modern OpenGL with shaders / programmatic pipeline -// - Desktop GL: 2.x 3.x 4.x -// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0) -// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..) - -// Implemented features: -// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about -// ImTextureID! [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices (Desktop OpenGL only). [X] -// Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= -// ImGuiConfigFlags_ViewportsEnable'. - -// About WebGL/ES: -// - You need to '#define IMGUI_IMPL_OPENGL_ES2' or '#define IMGUI_IMPL_OPENGL_ES3' to use WebGL or OpenGL ES. -// - This is done automatically on iOS, Android and Emscripten targets. -// - For other targets, the define needs to be visible from the imgui_impl_opengl3.cpp compilation unit. If unsure, -// define globally or in imconfig.h. - -// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. -// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build -// the backends you need. If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of -// imgui.cpp. Read online: https://github.com/ocornut/imgui/tree/master/docs - -// About GLSL version: -// The 'glsl_version' initialization parameter should be nullptr (default) or a "#version XXX" string. -// On computer platform the GLSL version default to "#version 130". On OpenGL ES 3 platform it defaults to "#version -// 300 es" Only override if your GL version doesn't handle this GLSL version. See GLSL version table at the top of -// imgui_impl_opengl3.cpp. - -#pragma once -#include "imgui.h" // IMGUI_IMPL_API - -// Backend API -IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char *glsl_version = nullptr); -IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown(); -IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame(); -IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData *draw_data); - -// (Optional) Called by Init/NewFrame/Shutdown -IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateFontsTexture(); -IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyFontsTexture(); -IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects(); -IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects(); - -// Specific OpenGL ES versions -// #define IMGUI_IMPL_OPENGL_ES2 // Auto-detected on Emscripten -// #define IMGUI_IMPL_OPENGL_ES3 // Auto-detected on iOS/Android - -// You can explicitly select GLES2 or GLES3 API by using one of the '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h -// or compiler command-line. -#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) - -// Try to detect GLES on matching platforms -# if defined(__APPLE__) -# include -# endif -# if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__)) -# define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es" -# elif defined(__EMSCRIPTEN__) || defined(__amigaos4__) -# define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100" -# else -// Otherwise imgui_impl_opengl3_loader.h will be used. -# endif - -#endif diff --git a/src/backends/imgui_impl_opengl3_loader.h b/src/backends/imgui_impl_opengl3_loader.h deleted file mode 100644 index 08cca9d..0000000 --- a/src/backends/imgui_impl_opengl3_loader.h +++ /dev/null @@ -1,844 +0,0 @@ -//----------------------------------------------------------------------------- -// About imgui_impl_opengl3_loader.h: -// -// We embed our own OpenGL loader to not require user to provide their own or to have to use ours, -// which proved to be endless problems for users. -// Our loader is custom-generated, based on gl3w but automatically filtered to only include -// enums/functions that we use in our imgui_impl_opengl3.cpp source file in order to be small. -// -// YOU SHOULD NOT NEED TO INCLUDE/USE THIS DIRECTLY. THIS IS USED BY imgui_impl_opengl3.cpp ONLY. -// THE REST OF YOUR APP SHOULD USE A DIFFERENT GL LOADER: ANY GL LOADER OF YOUR CHOICE. -// -// IF YOU GET BUILD ERRORS IN THIS FILE (commonly macro redefinitions or function redefinitions): -// IT LIKELY MEANS THAT YOU ARE BUILDING 'imgui_impl_opengl3.cpp' OR INCUDING 'imgui_impl_opengl3_loader.h' -// IN THE SAME COMPILATION UNIT AS ONE OF YOUR FILE WHICH IS USING A THIRD-PARTY OPENGL LOADER. -// (e.g. COULD HAPPEN IF YOU ARE DOING A UNITY/JUMBO BUILD, OR INCLUDING .CPP FILES FROM OTHERS) -// YOU SHOULD NOT BUILD BOTH IN THE SAME COMPILATION UNIT. -// BUT IF YOU REALLY WANT TO, you can '#define IMGUI_IMPL_OPENGL_LOADER_CUSTOM' and imgui_impl_opengl3.cpp -// WILL NOT BE USING OUR LOADER, AND INSTEAD EXPECT ANOTHER/YOUR LOADER TO BE AVAILABLE IN THE COMPILATION UNIT. -// -// Regenerate with: -// python gl3w_gen.py --output ../imgui/backends/imgui_impl_opengl3_loader.h --ref -// ../imgui/backends/imgui_impl_opengl3.cpp ./extra_symbols.txt -// -// More info: -// https://github.com/dearimgui/gl3w_stripped -// https://github.com/ocornut/imgui/issues/4445 -//----------------------------------------------------------------------------- - -/* - * This file was generated with gl3w_gen.py, part of imgl3w - * (hosted at https://github.com/dearimgui/gl3w_stripped) - * - * This is free and unencumbered software released into the public domain. - * - * Anyone is free to copy, modify, publish, use, compile, sell, or - * distribute this software, either in source code form or as a compiled - * binary, for any purpose, commercial or non-commercial, and by any - * means. - * - * In jurisdictions that recognize copyright laws, the author or authors - * of this software dedicate any and all copyright interest in the - * software to the public domain. We make this dedication for the benefit - * of the public at large and to the detriment of our heirs and - * successors. We intend this dedication to be an overt act of - * relinquishment in perpetuity of all present and future rights to this - * software under copyright law. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef __gl3w_h_ -#define __gl3w_h_ - -// Adapted from KHR/khrplatform.h to avoid including entire file. -#ifndef __khrplatform_h_ -typedef float khronos_float_t; -typedef signed char khronos_int8_t; -typedef unsigned char khronos_uint8_t; -typedef signed short int khronos_int16_t; -typedef unsigned short int khronos_uint16_t; -# ifdef _WIN64 -typedef signed long long int khronos_intptr_t; -typedef signed long long int khronos_ssize_t; -# else -typedef signed long int khronos_intptr_t; -typedef signed long int khronos_ssize_t; -# endif - -# if defined(_MSC_VER) && !defined(__clang__) -typedef signed __int64 khronos_int64_t; -typedef unsigned __int64 khronos_uint64_t; -# elif (defined(__clang__) || defined(__GNUC__)) && (__cplusplus < 201100) -# include -typedef int64_t khronos_int64_t; -typedef uint64_t khronos_uint64_t; -# else -typedef signed long long khronos_int64_t; -typedef unsigned long long khronos_uint64_t; -# endif -#endif // __khrplatform_h_ - -#ifndef __gl_glcorearb_h_ -# define __gl_glcorearb_h_ 1 -# ifdef __cplusplus -extern "C" -{ -# endif -/* -** Copyright 2013-2020 The Khronos Group Inc. -** SPDX-License-Identifier: MIT -** -** This header is generated from the Khronos OpenGL / OpenGL ES XML -** API Registry. The current version of the Registry, generator scripts -** used to make the header, and the header can be found at -** https://github.com/KhronosGroup/OpenGL-Registry -*/ -# if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN 1 -# endif -# include -# endif -# ifndef APIENTRY -# define APIENTRY -# endif -# ifndef APIENTRYP -# define APIENTRYP APIENTRY * -# endif -# ifndef GLAPI -# define GLAPI extern -# endif -/* glcorearb.h is for use with OpenGL core profile implementations. -** It should should be placed in the same directory as gl.h and -** included as . -** -** glcorearb.h includes only APIs in the latest OpenGL core profile -** implementation together with APIs in newer ARB extensions which -** can be supported by the core profile. It does not, and never will -** include functionality removed from the core profile, such as -** fixed-function vertex and fragment processing. -** -** Do not #include both and either of or -** in the same source file. -*/ -/* Generated C header for: - * API: gl - * Profile: core - * Versions considered: .* - * Versions emitted: .* - * Default extensions included: glcore - * Additional extensions included: _nomatch_^ - * Extensions removed: _nomatch_^ - */ -# ifndef GL_VERSION_1_0 - typedef void GLvoid; - typedef unsigned int GLenum; - - typedef khronos_float_t GLfloat; - typedef int GLint; - typedef int GLsizei; - typedef unsigned int GLbitfield; - typedef double GLdouble; - typedef unsigned int GLuint; - typedef unsigned char GLboolean; - typedef khronos_uint8_t GLubyte; -# define GL_COLOR_BUFFER_BIT 0x00004000 -# define GL_FALSE 0 -# define GL_TRUE 1 -# define GL_TRIANGLES 0x0004 -# define GL_ONE 1 -# define GL_SRC_ALPHA 0x0302 -# define GL_ONE_MINUS_SRC_ALPHA 0x0303 -# define GL_FRONT 0x0404 -# define GL_BACK 0x0405 -# define GL_FRONT_AND_BACK 0x0408 -# define GL_POLYGON_MODE 0x0B40 -# define GL_CULL_FACE 0x0B44 -# define GL_DEPTH_TEST 0x0B71 -# define GL_STENCIL_TEST 0x0B90 -# define GL_VIEWPORT 0x0BA2 -# define GL_BLEND 0x0BE2 -# define GL_SCISSOR_BOX 0x0C10 -# define GL_SCISSOR_TEST 0x0C11 -# define GL_UNPACK_ROW_LENGTH 0x0CF2 -# define GL_PACK_ALIGNMENT 0x0D05 -# define GL_TEXTURE_2D 0x0DE1 -# define GL_UNSIGNED_BYTE 0x1401 -# define GL_UNSIGNED_SHORT 0x1403 -# define GL_UNSIGNED_INT 0x1405 -# define GL_FLOAT 0x1406 -# define GL_RGBA 0x1908 -# define GL_FILL 0x1B02 -# define GL_VENDOR 0x1F00 -# define GL_RENDERER 0x1F01 -# define GL_VERSION 0x1F02 -# define GL_EXTENSIONS 0x1F03 -# define GL_LINEAR 0x2601 -# define GL_TEXTURE_MAG_FILTER 0x2800 -# define GL_TEXTURE_MIN_FILTER 0x2801 - typedef void(APIENTRYP PFNGLPOLYGONMODEPROC)(GLenum face, GLenum mode); - typedef void(APIENTRYP PFNGLSCISSORPROC)(GLint x, GLint y, GLsizei width, GLsizei height); - typedef void(APIENTRYP PFNGLTEXPARAMETERIPROC)(GLenum target, GLenum pname, GLint param); - typedef void(APIENTRYP PFNGLTEXIMAGE2DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, - GLsizei height, GLint border, GLenum format, GLenum type, - const void *pixels); - typedef void(APIENTRYP PFNGLCLEARPROC)(GLbitfield mask); - typedef void(APIENTRYP PFNGLCLEARCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); - typedef void(APIENTRYP PFNGLDISABLEPROC)(GLenum cap); - typedef void(APIENTRYP PFNGLENABLEPROC)(GLenum cap); - typedef void(APIENTRYP PFNGLFLUSHPROC)(void); - typedef void(APIENTRYP PFNGLPIXELSTOREIPROC)(GLenum pname, GLint param); - typedef void(APIENTRYP PFNGLREADPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, - GLenum type, void *pixels); - typedef GLenum(APIENTRYP PFNGLGETERRORPROC)(void); - typedef void(APIENTRYP PFNGLGETINTEGERVPROC)(GLenum pname, GLint *data); - typedef const GLubyte *(APIENTRYP PFNGLGETSTRINGPROC)(GLenum name); - typedef GLboolean(APIENTRYP PFNGLISENABLEDPROC)(GLenum cap); - typedef void(APIENTRYP PFNGLVIEWPORTPROC)(GLint x, GLint y, GLsizei width, GLsizei height); -# ifdef GL_GLEXT_PROTOTYPES - GLAPI void APIENTRY glPolygonMode(GLenum face, GLenum mode); - GLAPI void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height); - GLAPI void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param); - GLAPI void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, - GLint border, GLenum format, GLenum type, const void *pixels); - GLAPI void APIENTRY glClear(GLbitfield mask); - GLAPI void APIENTRY glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); - GLAPI void APIENTRY glDisable(GLenum cap); - GLAPI void APIENTRY glEnable(GLenum cap); - GLAPI void APIENTRY glFlush(void); - GLAPI void APIENTRY glPixelStorei(GLenum pname, GLint param); - GLAPI void APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, - void *pixels); - GLAPI GLenum APIENTRY glGetError(void); - GLAPI void APIENTRY glGetIntegerv(GLenum pname, GLint *data); - GLAPI const GLubyte *APIENTRY glGetString(GLenum name); - GLAPI GLboolean APIENTRY glIsEnabled(GLenum cap); - GLAPI void APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height); -# endif -# endif /* GL_VERSION_1_0 */ -# ifndef GL_VERSION_1_1 - typedef khronos_float_t GLclampf; - typedef double GLclampd; -# define GL_TEXTURE_BINDING_2D 0x8069 - typedef void(APIENTRYP PFNGLDRAWELEMENTSPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices); - typedef void(APIENTRYP PFNGLBINDTEXTUREPROC)(GLenum target, GLuint texture); - typedef void(APIENTRYP PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint *textures); - typedef void(APIENTRYP PFNGLGENTEXTURESPROC)(GLsizei n, GLuint *textures); -# ifdef GL_GLEXT_PROTOTYPES - GLAPI void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices); - GLAPI void APIENTRY glBindTexture(GLenum target, GLuint texture); - GLAPI void APIENTRY glDeleteTextures(GLsizei n, const GLuint *textures); - GLAPI void APIENTRY glGenTextures(GLsizei n, GLuint *textures); -# endif -# endif /* GL_VERSION_1_1 */ -# ifndef GL_VERSION_1_3 -# define GL_TEXTURE0 0x84C0 -# define GL_ACTIVE_TEXTURE 0x84E0 - typedef void(APIENTRYP PFNGLACTIVETEXTUREPROC)(GLenum texture); -# ifdef GL_GLEXT_PROTOTYPES - GLAPI void APIENTRY glActiveTexture(GLenum texture); -# endif -# endif /* GL_VERSION_1_3 */ -# ifndef GL_VERSION_1_4 -# define GL_BLEND_DST_RGB 0x80C8 -# define GL_BLEND_SRC_RGB 0x80C9 -# define GL_BLEND_DST_ALPHA 0x80CA -# define GL_BLEND_SRC_ALPHA 0x80CB -# define GL_FUNC_ADD 0x8006 - typedef void(APIENTRYP PFNGLBLENDFUNCSEPARATEPROC)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, - GLenum dfactorAlpha); - typedef void(APIENTRYP PFNGLBLENDEQUATIONPROC)(GLenum mode); -# ifdef GL_GLEXT_PROTOTYPES - GLAPI void APIENTRY glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, - GLenum dfactorAlpha); - GLAPI void APIENTRY glBlendEquation(GLenum mode); -# endif -# endif /* GL_VERSION_1_4 */ -# ifndef GL_VERSION_1_5 - typedef khronos_ssize_t GLsizeiptr; - typedef khronos_intptr_t GLintptr; -# define GL_ARRAY_BUFFER 0x8892 -# define GL_ELEMENT_ARRAY_BUFFER 0x8893 -# define GL_ARRAY_BUFFER_BINDING 0x8894 -# define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 -# define GL_STREAM_DRAW 0x88E0 - typedef void(APIENTRYP PFNGLBINDBUFFERPROC)(GLenum target, GLuint buffer); - typedef void(APIENTRYP PFNGLDELETEBUFFERSPROC)(GLsizei n, const GLuint *buffers); - typedef void(APIENTRYP PFNGLGENBUFFERSPROC)(GLsizei n, GLuint *buffers); - typedef void(APIENTRYP PFNGLBUFFERDATAPROC)(GLenum target, GLsizeiptr size, const void *data, GLenum usage); - typedef void(APIENTRYP PFNGLBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, const void *data); -# ifdef GL_GLEXT_PROTOTYPES - GLAPI void APIENTRY glBindBuffer(GLenum target, GLuint buffer); - GLAPI void APIENTRY glDeleteBuffers(GLsizei n, const GLuint *buffers); - GLAPI void APIENTRY glGenBuffers(GLsizei n, GLuint *buffers); - GLAPI void APIENTRY glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage); - GLAPI void APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data); -# endif -# endif /* GL_VERSION_1_5 */ -# ifndef GL_VERSION_2_0 - typedef char GLchar; - typedef khronos_int16_t GLshort; - typedef khronos_int8_t GLbyte; - typedef khronos_uint16_t GLushort; -# define GL_BLEND_EQUATION_RGB 0x8009 -# define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 -# define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 -# define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 -# define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 -# define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 -# define GL_BLEND_EQUATION_ALPHA 0x883D -# define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A -# define GL_FRAGMENT_SHADER 0x8B30 -# define GL_VERTEX_SHADER 0x8B31 -# define GL_COMPILE_STATUS 0x8B81 -# define GL_LINK_STATUS 0x8B82 -# define GL_INFO_LOG_LENGTH 0x8B84 -# define GL_CURRENT_PROGRAM 0x8B8D -# define GL_UPPER_LEFT 0x8CA2 - typedef void(APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum modeRGB, GLenum modeAlpha); - typedef void(APIENTRYP PFNGLATTACHSHADERPROC)(GLuint program, GLuint shader); - typedef void(APIENTRYP PFNGLCOMPILESHADERPROC)(GLuint shader); - typedef GLuint(APIENTRYP PFNGLCREATEPROGRAMPROC)(void); - typedef GLuint(APIENTRYP PFNGLCREATESHADERPROC)(GLenum type); - typedef void(APIENTRYP PFNGLDELETEPROGRAMPROC)(GLuint program); - typedef void(APIENTRYP PFNGLDELETESHADERPROC)(GLuint shader); - typedef void(APIENTRYP PFNGLDETACHSHADERPROC)(GLuint program, GLuint shader); - typedef void(APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint index); - typedef void(APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint index); - typedef GLint(APIENTRYP PFNGLGETATTRIBLOCATIONPROC)(GLuint program, const GLchar *name); - typedef void(APIENTRYP PFNGLGETPROGRAMIVPROC)(GLuint program, GLenum pname, GLint *params); - typedef void(APIENTRYP PFNGLGETPROGRAMINFOLOGPROC)(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); - typedef void(APIENTRYP PFNGLGETSHADERIVPROC)(GLuint shader, GLenum pname, GLint *params); - typedef void(APIENTRYP PFNGLGETSHADERINFOLOGPROC)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); - typedef GLint(APIENTRYP PFNGLGETUNIFORMLOCATIONPROC)(GLuint program, const GLchar *name); - typedef void(APIENTRYP PFNGLGETVERTEXATTRIBIVPROC)(GLuint index, GLenum pname, GLint *params); - typedef void(APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint index, GLenum pname, void **pointer); - typedef GLboolean(APIENTRYP PFNGLISPROGRAMPROC)(GLuint program); - typedef void(APIENTRYP PFNGLLINKPROGRAMPROC)(GLuint program); - typedef void(APIENTRYP PFNGLSHADERSOURCEPROC)(GLuint shader, GLsizei count, const GLchar *const *string, - const GLint *length); - typedef void(APIENTRYP PFNGLUSEPROGRAMPROC)(GLuint program); - typedef void(APIENTRYP PFNGLUNIFORM1IPROC)(GLint location, GLint v0); - typedef void(APIENTRYP PFNGLUNIFORMMATRIX4FVPROC)(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value); - typedef void(APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, - GLsizei stride, const void *pointer); -# ifdef GL_GLEXT_PROTOTYPES - GLAPI void APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha); - GLAPI void APIENTRY glAttachShader(GLuint program, GLuint shader); - GLAPI void APIENTRY glCompileShader(GLuint shader); - GLAPI GLuint APIENTRY glCreateProgram(void); - GLAPI GLuint APIENTRY glCreateShader(GLenum type); - GLAPI void APIENTRY glDeleteProgram(GLuint program); - GLAPI void APIENTRY glDeleteShader(GLuint shader); - GLAPI void APIENTRY glDetachShader(GLuint program, GLuint shader); - GLAPI void APIENTRY glDisableVertexAttribArray(GLuint index); - GLAPI void APIENTRY glEnableVertexAttribArray(GLuint index); - GLAPI GLint APIENTRY glGetAttribLocation(GLuint program, const GLchar *name); - GLAPI void APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint *params); - GLAPI void APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); - GLAPI void APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint *params); - GLAPI void APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); - GLAPI GLint APIENTRY glGetUniformLocation(GLuint program, const GLchar *name); - GLAPI void APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint *params); - GLAPI void APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, void **pointer); - GLAPI GLboolean APIENTRY glIsProgram(GLuint program); - GLAPI void APIENTRY glLinkProgram(GLuint program); - GLAPI void APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length); - GLAPI void APIENTRY glUseProgram(GLuint program); - GLAPI void APIENTRY glUniform1i(GLint location, GLint v0); - GLAPI void APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - GLAPI void APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, - const void *pointer); -# endif -# endif /* GL_VERSION_2_0 */ -# ifndef GL_VERSION_3_0 - typedef khronos_uint16_t GLhalf; -# define GL_MAJOR_VERSION 0x821B -# define GL_MINOR_VERSION 0x821C -# define GL_NUM_EXTENSIONS 0x821D -# define GL_FRAMEBUFFER_SRGB 0x8DB9 -# define GL_VERTEX_ARRAY_BINDING 0x85B5 - typedef void(APIENTRYP PFNGLGETBOOLEANI_VPROC)(GLenum target, GLuint index, GLboolean *data); - typedef void(APIENTRYP PFNGLGETINTEGERI_VPROC)(GLenum target, GLuint index, GLint *data); - typedef const GLubyte *(APIENTRYP PFNGLGETSTRINGIPROC)(GLenum name, GLuint index); - typedef void(APIENTRYP PFNGLBINDVERTEXARRAYPROC)(GLuint array); - typedef void(APIENTRYP PFNGLDELETEVERTEXARRAYSPROC)(GLsizei n, const GLuint *arrays); - typedef void(APIENTRYP PFNGLGENVERTEXARRAYSPROC)(GLsizei n, GLuint *arrays); -# ifdef GL_GLEXT_PROTOTYPES - GLAPI const GLubyte *APIENTRY glGetStringi(GLenum name, GLuint index); - GLAPI void APIENTRY glBindVertexArray(GLuint array); - GLAPI void APIENTRY glDeleteVertexArrays(GLsizei n, const GLuint *arrays); - GLAPI void APIENTRY glGenVertexArrays(GLsizei n, GLuint *arrays); -# endif -# endif /* GL_VERSION_3_0 */ -# ifndef GL_VERSION_3_1 -# define GL_VERSION_3_1 1 -# define GL_PRIMITIVE_RESTART 0x8F9D -# endif /* GL_VERSION_3_1 */ -# ifndef GL_VERSION_3_2 -# define GL_VERSION_3_2 1 - typedef struct __GLsync *GLsync; - typedef khronos_uint64_t GLuint64; - typedef khronos_int64_t GLint64; -# define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 -# define GL_CONTEXT_PROFILE_MASK 0x9126 - typedef void(APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices, - GLint basevertex); - typedef void(APIENTRYP PFNGLGETINTEGER64I_VPROC)(GLenum target, GLuint index, GLint64 *data); -# ifdef GL_GLEXT_PROTOTYPES - GLAPI void APIENTRY glDrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const void *indices, - GLint basevertex); -# endif -# endif /* GL_VERSION_3_2 */ -# ifndef GL_VERSION_3_3 -# define GL_VERSION_3_3 1 -# define GL_SAMPLER_BINDING 0x8919 - typedef void(APIENTRYP PFNGLBINDSAMPLERPROC)(GLuint unit, GLuint sampler); -# ifdef GL_GLEXT_PROTOTYPES - GLAPI void APIENTRY glBindSampler(GLuint unit, GLuint sampler); -# endif -# endif /* GL_VERSION_3_3 */ -# ifndef GL_VERSION_4_1 - typedef void(APIENTRYP PFNGLGETFLOATI_VPROC)(GLenum target, GLuint index, GLfloat *data); - typedef void(APIENTRYP PFNGLGETDOUBLEI_VPROC)(GLenum target, GLuint index, GLdouble *data); -# endif /* GL_VERSION_4_1 */ -# ifndef GL_VERSION_4_3 - typedef void(APIENTRY *GLDEBUGPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, - const GLchar *message, const void *userParam); -# endif /* GL_VERSION_4_3 */ -# ifndef GL_VERSION_4_5 -# define GL_CLIP_ORIGIN 0x935C - typedef void(APIENTRYP PFNGLGETTRANSFORMFEEDBACKI_VPROC)(GLuint xfb, GLenum pname, GLuint index, GLint *param); - typedef void(APIENTRYP PFNGLGETTRANSFORMFEEDBACKI64_VPROC)(GLuint xfb, GLenum pname, GLuint index, GLint64 *param); -# endif /* GL_VERSION_4_5 */ -# ifndef GL_ARB_bindless_texture - typedef khronos_uint64_t GLuint64EXT; -# endif /* GL_ARB_bindless_texture */ -# ifndef GL_ARB_cl_event - struct _cl_context; - struct _cl_event; -# endif /* GL_ARB_cl_event */ -# ifndef GL_ARB_clip_control -# define GL_ARB_clip_control 1 -# endif /* GL_ARB_clip_control */ -# ifndef GL_ARB_debug_output - typedef void(APIENTRY *GLDEBUGPROCARB)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, - const GLchar *message, const void *userParam); -# endif /* GL_ARB_debug_output */ -# ifndef GL_EXT_EGL_image_storage - typedef void *GLeglImageOES; -# endif /* GL_EXT_EGL_image_storage */ -# ifndef GL_EXT_direct_state_access - typedef void(APIENTRYP PFNGLGETFLOATI_VEXTPROC)(GLenum pname, GLuint index, GLfloat *params); - typedef void(APIENTRYP PFNGLGETDOUBLEI_VEXTPROC)(GLenum pname, GLuint index, GLdouble *params); - typedef void(APIENTRYP PFNGLGETPOINTERI_VEXTPROC)(GLenum pname, GLuint index, void **params); - typedef void(APIENTRYP PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC)(GLuint vaobj, GLuint index, GLenum pname, GLint *param); - typedef void(APIENTRYP PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC)(GLuint vaobj, GLuint index, GLenum pname, void **param); -# endif /* GL_EXT_direct_state_access */ -# ifndef GL_NV_draw_vulkan_image - typedef void(APIENTRY *GLVULKANPROCNV)(void); -# endif /* GL_NV_draw_vulkan_image */ -# ifndef GL_NV_gpu_shader5 - typedef khronos_int64_t GLint64EXT; -# endif /* GL_NV_gpu_shader5 */ -# ifndef GL_NV_vertex_buffer_unified_memory - typedef void(APIENTRYP PFNGLGETINTEGERUI64I_VNVPROC)(GLenum value, GLuint index, GLuint64EXT *result); -# endif /* GL_NV_vertex_buffer_unified_memory */ -# ifdef __cplusplus -} -# endif -#endif - -#ifndef GL3W_API -# define GL3W_API -#endif - -#ifndef __gl_h_ -# define __gl_h_ -#endif - -#ifdef __cplusplus -extern "C" -{ -#endif - -#define GL3W_OK 0 -#define GL3W_ERROR_INIT -1 -#define GL3W_ERROR_LIBRARY_OPEN -2 -#define GL3W_ERROR_OPENGL_VERSION -3 - - typedef void (*GL3WglProc)(void); - typedef GL3WglProc (*GL3WGetProcAddressProc)(const char *proc); - - /* gl3w api */ - GL3W_API int imgl3wInit(void); - GL3W_API int imgl3wInit2(GL3WGetProcAddressProc proc); - GL3W_API int imgl3wIsSupported(int major, int minor); - GL3W_API GL3WglProc imgl3wGetProcAddress(const char *proc); - - /* gl3w internal state */ - union GL3WProcs { - GL3WglProc ptr[59]; - struct - { - PFNGLACTIVETEXTUREPROC ActiveTexture; - PFNGLATTACHSHADERPROC AttachShader; - PFNGLBINDBUFFERPROC BindBuffer; - PFNGLBINDSAMPLERPROC BindSampler; - PFNGLBINDTEXTUREPROC BindTexture; - PFNGLBINDVERTEXARRAYPROC BindVertexArray; - PFNGLBLENDEQUATIONPROC BlendEquation; - PFNGLBLENDEQUATIONSEPARATEPROC BlendEquationSeparate; - PFNGLBLENDFUNCSEPARATEPROC BlendFuncSeparate; - PFNGLBUFFERDATAPROC BufferData; - PFNGLBUFFERSUBDATAPROC BufferSubData; - PFNGLCLEARPROC Clear; - PFNGLCLEARCOLORPROC ClearColor; - PFNGLCOMPILESHADERPROC CompileShader; - PFNGLCREATEPROGRAMPROC CreateProgram; - PFNGLCREATESHADERPROC CreateShader; - PFNGLDELETEBUFFERSPROC DeleteBuffers; - PFNGLDELETEPROGRAMPROC DeleteProgram; - PFNGLDELETESHADERPROC DeleteShader; - PFNGLDELETETEXTURESPROC DeleteTextures; - PFNGLDELETEVERTEXARRAYSPROC DeleteVertexArrays; - PFNGLDETACHSHADERPROC DetachShader; - PFNGLDISABLEPROC Disable; - PFNGLDISABLEVERTEXATTRIBARRAYPROC DisableVertexAttribArray; - PFNGLDRAWELEMENTSPROC DrawElements; - PFNGLDRAWELEMENTSBASEVERTEXPROC DrawElementsBaseVertex; - PFNGLENABLEPROC Enable; - PFNGLENABLEVERTEXATTRIBARRAYPROC EnableVertexAttribArray; - PFNGLFLUSHPROC Flush; - PFNGLGENBUFFERSPROC GenBuffers; - PFNGLGENTEXTURESPROC GenTextures; - PFNGLGENVERTEXARRAYSPROC GenVertexArrays; - PFNGLGETATTRIBLOCATIONPROC GetAttribLocation; - PFNGLGETERRORPROC GetError; - PFNGLGETINTEGERVPROC GetIntegerv; - PFNGLGETPROGRAMINFOLOGPROC GetProgramInfoLog; - PFNGLGETPROGRAMIVPROC GetProgramiv; - PFNGLGETSHADERINFOLOGPROC GetShaderInfoLog; - PFNGLGETSHADERIVPROC GetShaderiv; - PFNGLGETSTRINGPROC GetString; - PFNGLGETSTRINGIPROC GetStringi; - PFNGLGETUNIFORMLOCATIONPROC GetUniformLocation; - PFNGLGETVERTEXATTRIBPOINTERVPROC GetVertexAttribPointerv; - PFNGLGETVERTEXATTRIBIVPROC GetVertexAttribiv; - PFNGLISENABLEDPROC IsEnabled; - PFNGLISPROGRAMPROC IsProgram; - PFNGLLINKPROGRAMPROC LinkProgram; - PFNGLPIXELSTOREIPROC PixelStorei; - PFNGLPOLYGONMODEPROC PolygonMode; - PFNGLREADPIXELSPROC ReadPixels; - PFNGLSCISSORPROC Scissor; - PFNGLSHADERSOURCEPROC ShaderSource; - PFNGLTEXIMAGE2DPROC TexImage2D; - PFNGLTEXPARAMETERIPROC TexParameteri; - PFNGLUNIFORM1IPROC Uniform1i; - PFNGLUNIFORMMATRIX4FVPROC UniformMatrix4fv; - PFNGLUSEPROGRAMPROC UseProgram; - PFNGLVERTEXATTRIBPOINTERPROC VertexAttribPointer; - PFNGLVIEWPORTPROC Viewport; - } gl; - }; - - GL3W_API extern union GL3WProcs imgl3wProcs; - -/* OpenGL functions */ -#define glActiveTexture imgl3wProcs.gl.ActiveTexture -#define glAttachShader imgl3wProcs.gl.AttachShader -#define glBindBuffer imgl3wProcs.gl.BindBuffer -#define glBindSampler imgl3wProcs.gl.BindSampler -#define glBindTexture imgl3wProcs.gl.BindTexture -#define glBindVertexArray imgl3wProcs.gl.BindVertexArray -#define glBlendEquation imgl3wProcs.gl.BlendEquation -#define glBlendEquationSeparate imgl3wProcs.gl.BlendEquationSeparate -#define glBlendFuncSeparate imgl3wProcs.gl.BlendFuncSeparate -#define glBufferData imgl3wProcs.gl.BufferData -#define glBufferSubData imgl3wProcs.gl.BufferSubData -#define glClear imgl3wProcs.gl.Clear -#define glClearColor imgl3wProcs.gl.ClearColor -#define glCompileShader imgl3wProcs.gl.CompileShader -#define glCreateProgram imgl3wProcs.gl.CreateProgram -#define glCreateShader imgl3wProcs.gl.CreateShader -#define glDeleteBuffers imgl3wProcs.gl.DeleteBuffers -#define glDeleteProgram imgl3wProcs.gl.DeleteProgram -#define glDeleteShader imgl3wProcs.gl.DeleteShader -#define glDeleteTextures imgl3wProcs.gl.DeleteTextures -#define glDeleteVertexArrays imgl3wProcs.gl.DeleteVertexArrays -#define glDetachShader imgl3wProcs.gl.DetachShader -#define glDisable imgl3wProcs.gl.Disable -#define glDisableVertexAttribArray imgl3wProcs.gl.DisableVertexAttribArray -#define glDrawElements imgl3wProcs.gl.DrawElements -#define glDrawElementsBaseVertex imgl3wProcs.gl.DrawElementsBaseVertex -#define glEnable imgl3wProcs.gl.Enable -#define glEnableVertexAttribArray imgl3wProcs.gl.EnableVertexAttribArray -#define glFlush imgl3wProcs.gl.Flush -#define glGenBuffers imgl3wProcs.gl.GenBuffers -#define glGenTextures imgl3wProcs.gl.GenTextures -#define glGenVertexArrays imgl3wProcs.gl.GenVertexArrays -#define glGetAttribLocation imgl3wProcs.gl.GetAttribLocation -#define glGetError imgl3wProcs.gl.GetError -#define glGetIntegerv imgl3wProcs.gl.GetIntegerv -#define glGetProgramInfoLog imgl3wProcs.gl.GetProgramInfoLog -#define glGetProgramiv imgl3wProcs.gl.GetProgramiv -#define glGetShaderInfoLog imgl3wProcs.gl.GetShaderInfoLog -#define glGetShaderiv imgl3wProcs.gl.GetShaderiv -#define glGetString imgl3wProcs.gl.GetString -#define glGetStringi imgl3wProcs.gl.GetStringi -#define glGetUniformLocation imgl3wProcs.gl.GetUniformLocation -#define glGetVertexAttribPointerv imgl3wProcs.gl.GetVertexAttribPointerv -#define glGetVertexAttribiv imgl3wProcs.gl.GetVertexAttribiv -#define glIsEnabled imgl3wProcs.gl.IsEnabled -#define glIsProgram imgl3wProcs.gl.IsProgram -#define glLinkProgram imgl3wProcs.gl.LinkProgram -#define glPixelStorei imgl3wProcs.gl.PixelStorei -#define glPolygonMode imgl3wProcs.gl.PolygonMode -#define glReadPixels imgl3wProcs.gl.ReadPixels -#define glScissor imgl3wProcs.gl.Scissor -#define glShaderSource imgl3wProcs.gl.ShaderSource -#define glTexImage2D imgl3wProcs.gl.TexImage2D -#define glTexParameteri imgl3wProcs.gl.TexParameteri -#define glUniform1i imgl3wProcs.gl.Uniform1i -#define glUniformMatrix4fv imgl3wProcs.gl.UniformMatrix4fv -#define glUseProgram imgl3wProcs.gl.UseProgram -#define glVertexAttribPointer imgl3wProcs.gl.VertexAttribPointer -#define glViewport imgl3wProcs.gl.Viewport - -#ifdef __cplusplus -} -#endif - -#endif - -#ifdef IMGL3W_IMPL -#ifdef __cplusplus -extern "C" -{ -#endif - -#include - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - -#if defined(_WIN32) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN 1 -# endif -# include - - static HMODULE libgl; - typedef PROC(__stdcall *GL3WglGetProcAddr)(LPCSTR); - static GL3WglGetProcAddr wgl_get_proc_address; - - static int open_libgl(void) - { - libgl = LoadLibraryA("opengl32.dll"); - if (!libgl) - return GL3W_ERROR_LIBRARY_OPEN; - wgl_get_proc_address = (GL3WglGetProcAddr)GetProcAddress(libgl, "wglGetProcAddress"); - return GL3W_OK; - } - - static void close_libgl(void) - { - FreeLibrary(libgl); - } - static GL3WglProc get_proc(const char *proc) - { - GL3WglProc res; - res = (GL3WglProc)wgl_get_proc_address(proc); - if (!res) - res = (GL3WglProc)GetProcAddress(libgl, proc); - return res; - } -#elif defined(__APPLE__) -# include - -static void *libgl; -static int open_libgl(void) -{ - libgl = dlopen("/System/Library/Frameworks/OpenGL.framework/OpenGL", RTLD_LAZY | RTLD_LOCAL); - if (!libgl) - return GL3W_ERROR_LIBRARY_OPEN; - return GL3W_OK; -} - -static void close_libgl(void) -{ - dlclose(libgl); -} - -static GL3WglProc get_proc(const char *proc) -{ - GL3WglProc res; - *(void **)(&res) = dlsym(libgl, proc); - return res; -} -#else -# include - -static void *libgl; -static GL3WglProc (*glx_get_proc_address)(const GLubyte *); - -static int open_libgl(void) -{ - libgl = dlopen("libGL.so.1", RTLD_LAZY | RTLD_LOCAL); - if (!libgl) - return GL3W_ERROR_LIBRARY_OPEN; - *(void **)(&glx_get_proc_address) = dlsym(libgl, "glXGetProcAddressARB"); - return GL3W_OK; -} - -static void close_libgl(void) -{ - dlclose(libgl); -} - -static GL3WglProc get_proc(const char *proc) -{ - GL3WglProc res; - res = glx_get_proc_address((const GLubyte *)proc); - if (!res) - *(void **)(&res) = dlsym(libgl, proc); - return res; -} -#endif - - static struct - { - int major, minor; - } version; - - static int parse_version(void) - { - if (!glGetIntegerv) - return GL3W_ERROR_INIT; - glGetIntegerv(GL_MAJOR_VERSION, &version.major); - glGetIntegerv(GL_MINOR_VERSION, &version.minor); - if (version.major == 0 && version.minor == 0) - { - // Query GL_VERSION in desktop GL 2.x, the string will start with "." - if (const char *gl_version = (const char *)glGetString(GL_VERSION)) - sscanf(gl_version, "%d.%d", &version.major, &version.minor); - } - if (version.major < 2) - return GL3W_ERROR_OPENGL_VERSION; - return GL3W_OK; - } - - static void load_procs(GL3WGetProcAddressProc proc); - - int imgl3wInit(void) - { - int res = open_libgl(); - if (res) - return res; - atexit(close_libgl); - return imgl3wInit2(get_proc); - } - - int imgl3wInit2(GL3WGetProcAddressProc proc) - { - load_procs(proc); - return parse_version(); - } - - int imgl3wIsSupported(int major, int minor) - { - if (major < 2) - return 0; - if (version.major == major) - return version.minor >= minor; - return version.major >= major; - } - - GL3WglProc imgl3wGetProcAddress(const char *proc) - { - return get_proc(proc); - } - - static const char *proc_names[] = { - "glActiveTexture", - "glAttachShader", - "glBindBuffer", - "glBindSampler", - "glBindTexture", - "glBindVertexArray", - "glBlendEquation", - "glBlendEquationSeparate", - "glBlendFuncSeparate", - "glBufferData", - "glBufferSubData", - "glClear", - "glClearColor", - "glCompileShader", - "glCreateProgram", - "glCreateShader", - "glDeleteBuffers", - "glDeleteProgram", - "glDeleteShader", - "glDeleteTextures", - "glDeleteVertexArrays", - "glDetachShader", - "glDisable", - "glDisableVertexAttribArray", - "glDrawElements", - "glDrawElementsBaseVertex", - "glEnable", - "glEnableVertexAttribArray", - "glFlush", - "glGenBuffers", - "glGenTextures", - "glGenVertexArrays", - "glGetAttribLocation", - "glGetError", - "glGetIntegerv", - "glGetProgramInfoLog", - "glGetProgramiv", - "glGetShaderInfoLog", - "glGetShaderiv", - "glGetString", - "glGetStringi", - "glGetUniformLocation", - "glGetVertexAttribPointerv", - "glGetVertexAttribiv", - "glIsEnabled", - "glIsProgram", - "glLinkProgram", - "glPixelStorei", - "glPolygonMode", - "glReadPixels", - "glScissor", - "glShaderSource", - "glTexImage2D", - "glTexParameteri", - "glUniform1i", - "glUniformMatrix4fv", - "glUseProgram", - "glVertexAttribPointer", - "glViewport", - }; - - GL3W_API union GL3WProcs imgl3wProcs; - - static void load_procs(GL3WGetProcAddressProc proc) - { - size_t i; - for (i = 0; i < ARRAY_SIZE(proc_names); i++) - imgl3wProcs.ptr[i] = proc(proc_names[i]); - } - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/backends/imgui_impl_sdl2.cpp b/src/backends/imgui_impl_sdl2.cpp deleted file mode 100644 index efb7182..0000000 --- a/src/backends/imgui_impl_sdl2.cpp +++ /dev/null @@ -1,1227 +0,0 @@ -// dear imgui: Platform Backend for SDL2 -// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) -// (Info: SDL2 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, -// etc.) (Prefer SDL 2.0.5+ for full feature support.) - -// Implemented features: -// [X] Platform: Clipboard support. -// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen. -// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all -// key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless -// IMGUI_DISABLE_OBSOLETE_KEYIO is set] [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= -// ImGuiConfigFlags_NavEnableGamepad'. [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= -// ImGuiConfigFlags_NoMouseCursorChange'. [X] Platform: Multi-viewport support (multiple windows). Enable with -// 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. -// Missing features: -// [ ] Platform: Multi-viewport + Minimized windows seems to break mouse wheel events (at least under Windows). -// [x] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before -// SDL_CreateWindow()!. - -// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. -// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build -// the backends you need. If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of -// imgui.cpp. Read online: https://github.com/ocornut/imgui/tree/master/docs - -// CHANGELOG -// (minor and older changes stripped away, please see git history for details) -// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. -// 2023-04-06: Inputs: Avoid calling SDL_StartTextInput()/SDL_StopTextInput() as they don't only pertain to IME. It's -// unclear exactly what their relation is to IME. (#6306) 2023-04-04: Inputs: Added support for -// io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen. (#2702) 2023-02-23: -// Accept SDL_GetPerformanceCounter() not returning a monotonically increasing value. (#6189, #6114, #3644) 2023-02-07: -// Implement IME handler (io.SetPlatformImeDataFn will call SDL_SetTextInputRect()/SDL_StartTextInput()). 2023-02-07: -// *BREAKING CHANGE* Renamed this backend file from imgui_impl_sdl.cpp/.h to imgui_impl_sdl2.cpp/.h in prevision for -// the future release of SDL3. 2023-02-02: Avoid calling SDL_SetCursor() when cursor has not changed, as the function -// is surprisingly costly on Mac with latest SDL (may be fixed in next SDL version). 2023-02-02: Added support for -// SDL 2.0.18+ preciseX/preciseY mouse wheel data for smooth scrolling + Scaling X value on Emscripten (bug?). (#4019, -// #6096) 2023-02-02: Removed SDL_MOUSEWHEEL value clamping, as values seem correct in latest Emscripten. (#4019) -// 2023-02-01: Flipping SDL_MOUSEWHEEL 'wheel.x' value to match other backends and offer consistent horizontal -// scrolling direction. (#4019, #6096, #1463) 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. -// 2022-09-26: Inputs: Disable SDL 2.0.22 new "auto capture" (SDL_HINT_MOUSE_AUTO_CAPTURE) which prevents drag and drop -// across windows for multi-viewport support + don't capture when drag and dropping. (#5710) 2022-09-26: Inputs: -// Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported). 2022-03-22: Inputs: Fix -// mouse position issues when dragging outside of boundaries. SDL_CaptureMouse() erroneously still gives out LEAVE -// events when hovering OS decorations. 2022-03-22: Inputs: Added support for extra mouse buttons -// (SDL_BUTTON_X1/SDL_BUTTON_X2). 2022-02-04: Added SDL_Renderer* parameter to ImGui_ImplSDL2_InitForSDLRenderer(), so -// we can use SDL_GetRendererOutputSize() instead of SDL_GL_GetDrawableSize() when bound to a SDL_Renderer. 2022-01-26: -// Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago) with io.AddKeyEvent() using ImGuiKey_ModXXX -// flags. Sorry for the confusion. 2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support, instead -// of writing directly to io.NavInputs[]. 2022-01-17: Inputs: calling new io.AddMousePosEvent(), -// io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+). 2022-01-17: Inputs: always update key mods next and -// before key event (not in NewFrame) to fix input queue with very low framerates. 2022-01-12: Update mouse inputs -// using SDL_MOUSEMOTION/SDL_WINDOWEVENT_LEAVE + fallback to provide it when focused but not hovered/captured. More -// standard and will allow us to pass it to future input queue API. 2022-01-12: Maintain our own copy of -// MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted. 2022-01-10: Inputs: calling -// new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey -// range. 2021-08-17: Calling io.AddFocusEvent() on SDL_WINDOWEVENT_FOCUS_GAINED/SDL_WINDOWEVENT_FOCUS_LOST. -// 2021-07-29: Inputs: MousePos is correctly reported when the host platform window is hovered but not focused (using -// SDL_GetMouseFocus() + SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, requires SDL 2.0.5+) 2021-06:29: *BREAKING CHANGE* Removed -// 'SDL_Window* window' parameter to ImGui_ImplSDL2_NewFrame() which was unnecessary. 2021-06-29: Reorganized backend -// to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to -// bd->XXXX). 2021-03-22: Rework global mouse pos availability check listing supported platforms explicitly, -// effectively fixing mouse access on Raspberry Pi. (#2837, #3950) 2020-05-25: Misc: Report a zero display-size when -// window is minimized, to be consistent with other backends. 2020-02-20: Inputs: Fixed mapping for -// ImGuiKey_KeyPadEnter (using SDL_SCANCODE_KP_ENTER instead of SDL_SCANCODE_RETURN2). 2019-12-17: Inputs: On Wayland, -// use SDL_GetMouseState (because there is no global mouse state). 2019-12-05: Inputs: Added support for -// ImGuiMouseCursor_NotAllowed mouse cursor. 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter. 2019-04-23: -// Inputs: Added support for SDL_GameController (if ImGuiConfigFlags_NavEnableGamepad is set by user application). -// 2019-03-12: Misc: Preserve DisplayFramebufferScale when main window is minimized. -// 2018-12-21: Inputs: Workaround for Android/iOS which don't seem to handle focus related calls. -// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. -// 2018-11-14: Changed the signature of ImGui_ImplSDL2_ProcessEvent() to take a 'const SDL_Event*'. -// 2018-08-01: Inputs: Workaround for Emscripten which doesn't seem to handle focus related calls. -// 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor. -// 2018-06-08: Misc: Extracted imgui_impl_sdl.cpp/.h away from the old combined SDL2+OpenGL/Vulkan examples. -// 2018-06-08: Misc: ImGui_ImplSDL2_InitForOpenGL() now takes a SDL_GLContext parameter. -// 2018-05-09: Misc: Fixed clipboard paste memory leak (we didn't call SDL_FreeMemory on the data returned by -// SDL_GetClipboardText). 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors flag + honor -// ImGuiConfigFlags_NoMouseCursorChange flag. 2018-02-16: Inputs: Added support for mouse cursors, honoring -// ImGui::GetMouseCursor() value. 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 -// WIP, user needs to call CreateContext/DestroyContext themselves. 2018-02-06: Inputs: Added mapping for -// ImGuiKey_Space. 2018-02-05: Misc: Using SDL_GetPerformanceCounter() instead of SDL_GetTicks() to be able to handle -// very high framerate (1000+ FPS). 2018-02-05: Inputs: Keyboard mapping is using scancodes everywhere instead of a -// confusing mixture of keycodes and scancodes. 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. 2018-01-19: -// Inputs: When available (SDL 2.0.4+) using SDL_CaptureMouse() to retrieve coordinates outside of client area when -// dragging. Otherwise (SDL 2.0.3 and before) testing for SDL_WINDOW_INPUT_FOCUS instead of SDL_WINDOW_MOUSE_FOCUS. -// 2018-01-18: Inputs: Added mapping for ImGuiKey_Insert. -// 2017-08-25: Inputs: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1). -// 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers. - -#include "imgui_impl_sdl2.h" -#include "imgui.h" - -// Clang warnings with -Weverything -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored \ - "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision -#endif - -// SDL -// (the multi-viewports feature requires SDL features supported from SDL 2.0.4+. SDL 2.0.5+ is highly recommended) -#include -#include -#if defined(__APPLE__) -# include -#endif - -#if SDL_VERSION_ATLEAST(2, 0, 4) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && \ - !(defined(__APPLE__) && TARGET_OS_IOS) && !defined(__amigaos4__) -# define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 1 -#else -# define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 0 -#endif -#define SDL_HAS_WINDOW_ALPHA SDL_VERSION_ATLEAST(2, 0, 5) -#define SDL_HAS_ALWAYS_ON_TOP SDL_VERSION_ATLEAST(2, 0, 5) -#define SDL_HAS_USABLE_DISPLAY_BOUNDS SDL_VERSION_ATLEAST(2, 0, 5) -#define SDL_HAS_PER_MONITOR_DPI SDL_VERSION_ATLEAST(2, 0, 4) -#define SDL_HAS_VULKAN SDL_VERSION_ATLEAST(2, 0, 6) -#define SDL_HAS_DISPLAY_EVENT SDL_VERSION_ATLEAST(2, 0, 9) -#if !SDL_HAS_VULKAN -static const Uint32 SDL_WINDOW_VULKAN = 0x10000000; -#endif - -// SDL Data -struct ImGui_ImplSDL2_Data -{ - SDL_Window *Window; - SDL_Renderer *Renderer; - Uint64 Time; - Uint32 MouseWindowID; - int MouseButtonsDown; - SDL_Cursor *MouseCursors[ImGuiMouseCursor_COUNT]; - SDL_Cursor *LastMouseCursor; - int PendingMouseLeaveFrame; - char *ClipboardTextData; - bool MouseCanUseGlobalState; - bool MouseCanReportHoveredViewport; // This is hard to use/unreliable on SDL so we'll set - // ImGuiBackendFlags_HasMouseHoveredViewport dynamically based on state. - bool UseVulkan; - bool WantUpdateMonitors; - - ImGui_ImplSDL2_Data() - { - memset((void *)this, 0, sizeof(*this)); - } -}; - -// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts -// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple -// windows) instead of multiple Dear ImGui contexts. -// FIXME: multi-context support is not well tested and probably dysfunctional in this backend. -// FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context. -static ImGui_ImplSDL2_Data *ImGui_ImplSDL2_GetBackendData() -{ - return ImGui::GetCurrentContext() ? (ImGui_ImplSDL2_Data *)ImGui::GetIO().BackendPlatformUserData : nullptr; -} - -// Forward Declarations -static void ImGui_ImplSDL2_UpdateMonitors(); -static void ImGui_ImplSDL2_InitPlatformInterface(SDL_Window *window, void *sdl_gl_context); -static void ImGui_ImplSDL2_ShutdownPlatformInterface(); - -// Functions -static const char *ImGui_ImplSDL2_GetClipboardText(void *) -{ - ImGui_ImplSDL2_Data *bd = ImGui_ImplSDL2_GetBackendData(); - if (bd->ClipboardTextData) - SDL_free(bd->ClipboardTextData); - bd->ClipboardTextData = SDL_GetClipboardText(); - return bd->ClipboardTextData; -} - -static void ImGui_ImplSDL2_SetClipboardText(void *, const char *text) -{ - SDL_SetClipboardText(text); -} - -// Note: native IME will only display if user calls SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1") _before_ SDL_CreateWindow(). -static void ImGui_ImplSDL2_SetPlatformImeData(ImGuiViewport *viewport, ImGuiPlatformImeData *data) -{ - if (data->WantVisible) - { - SDL_Rect r; - r.x = (int)(data->InputPos.x - viewport->Pos.x); - r.y = (int)(data->InputPos.y - viewport->Pos.y + data->InputLineHeight); - r.w = 1; - r.h = (int)data->InputLineHeight; - SDL_SetTextInputRect(&r); - } -} - -static ImGuiKey ImGui_ImplSDL2_KeycodeToImGuiKey(int keycode) -{ - switch (keycode) - { - case SDLK_TAB: - return ImGuiKey_Tab; - case SDLK_LEFT: - return ImGuiKey_LeftArrow; - case SDLK_RIGHT: - return ImGuiKey_RightArrow; - case SDLK_UP: - return ImGuiKey_UpArrow; - case SDLK_DOWN: - return ImGuiKey_DownArrow; - case SDLK_PAGEUP: - return ImGuiKey_PageUp; - case SDLK_PAGEDOWN: - return ImGuiKey_PageDown; - case SDLK_HOME: - return ImGuiKey_Home; - case SDLK_END: - return ImGuiKey_End; - case SDLK_INSERT: - return ImGuiKey_Insert; - case SDLK_DELETE: - return ImGuiKey_Delete; - case SDLK_BACKSPACE: - return ImGuiKey_Backspace; - case SDLK_SPACE: - return ImGuiKey_Space; - case SDLK_RETURN: - return ImGuiKey_Enter; - case SDLK_ESCAPE: - return ImGuiKey_Escape; - case SDLK_QUOTE: - return ImGuiKey_Apostrophe; - case SDLK_COMMA: - return ImGuiKey_Comma; - case SDLK_MINUS: - return ImGuiKey_Minus; - case SDLK_PERIOD: - return ImGuiKey_Period; - case SDLK_SLASH: - return ImGuiKey_Slash; - case SDLK_SEMICOLON: - return ImGuiKey_Semicolon; - case SDLK_EQUALS: - return ImGuiKey_Equal; - case SDLK_LEFTBRACKET: - return ImGuiKey_LeftBracket; - case SDLK_BACKSLASH: - return ImGuiKey_Backslash; - case SDLK_RIGHTBRACKET: - return ImGuiKey_RightBracket; - case SDLK_BACKQUOTE: - return ImGuiKey_GraveAccent; - case SDLK_CAPSLOCK: - return ImGuiKey_CapsLock; - case SDLK_SCROLLLOCK: - return ImGuiKey_ScrollLock; - case SDLK_NUMLOCKCLEAR: - return ImGuiKey_NumLock; - case SDLK_PRINTSCREEN: - return ImGuiKey_PrintScreen; - case SDLK_PAUSE: - return ImGuiKey_Pause; - case SDLK_KP_0: - return ImGuiKey_Keypad0; - case SDLK_KP_1: - return ImGuiKey_Keypad1; - case SDLK_KP_2: - return ImGuiKey_Keypad2; - case SDLK_KP_3: - return ImGuiKey_Keypad3; - case SDLK_KP_4: - return ImGuiKey_Keypad4; - case SDLK_KP_5: - return ImGuiKey_Keypad5; - case SDLK_KP_6: - return ImGuiKey_Keypad6; - case SDLK_KP_7: - return ImGuiKey_Keypad7; - case SDLK_KP_8: - return ImGuiKey_Keypad8; - case SDLK_KP_9: - return ImGuiKey_Keypad9; - case SDLK_KP_PERIOD: - return ImGuiKey_KeypadDecimal; - case SDLK_KP_DIVIDE: - return ImGuiKey_KeypadDivide; - case SDLK_KP_MULTIPLY: - return ImGuiKey_KeypadMultiply; - case SDLK_KP_MINUS: - return ImGuiKey_KeypadSubtract; - case SDLK_KP_PLUS: - return ImGuiKey_KeypadAdd; - case SDLK_KP_ENTER: - return ImGuiKey_KeypadEnter; - case SDLK_KP_EQUALS: - return ImGuiKey_KeypadEqual; - case SDLK_LCTRL: - return ImGuiKey_LeftCtrl; - case SDLK_LSHIFT: - return ImGuiKey_LeftShift; - case SDLK_LALT: - return ImGuiKey_LeftAlt; - case SDLK_LGUI: - return ImGuiKey_LeftSuper; - case SDLK_RCTRL: - return ImGuiKey_RightCtrl; - case SDLK_RSHIFT: - return ImGuiKey_RightShift; - case SDLK_RALT: - return ImGuiKey_RightAlt; - case SDLK_RGUI: - return ImGuiKey_RightSuper; - case SDLK_APPLICATION: - return ImGuiKey_Menu; - case SDLK_0: - return ImGuiKey_0; - case SDLK_1: - return ImGuiKey_1; - case SDLK_2: - return ImGuiKey_2; - case SDLK_3: - return ImGuiKey_3; - case SDLK_4: - return ImGuiKey_4; - case SDLK_5: - return ImGuiKey_5; - case SDLK_6: - return ImGuiKey_6; - case SDLK_7: - return ImGuiKey_7; - case SDLK_8: - return ImGuiKey_8; - case SDLK_9: - return ImGuiKey_9; - case SDLK_a: - return ImGuiKey_A; - case SDLK_b: - return ImGuiKey_B; - case SDLK_c: - return ImGuiKey_C; - case SDLK_d: - return ImGuiKey_D; - case SDLK_e: - return ImGuiKey_E; - case SDLK_f: - return ImGuiKey_F; - case SDLK_g: - return ImGuiKey_G; - case SDLK_h: - return ImGuiKey_H; - case SDLK_i: - return ImGuiKey_I; - case SDLK_j: - return ImGuiKey_J; - case SDLK_k: - return ImGuiKey_K; - case SDLK_l: - return ImGuiKey_L; - case SDLK_m: - return ImGuiKey_M; - case SDLK_n: - return ImGuiKey_N; - case SDLK_o: - return ImGuiKey_O; - case SDLK_p: - return ImGuiKey_P; - case SDLK_q: - return ImGuiKey_Q; - case SDLK_r: - return ImGuiKey_R; - case SDLK_s: - return ImGuiKey_S; - case SDLK_t: - return ImGuiKey_T; - case SDLK_u: - return ImGuiKey_U; - case SDLK_v: - return ImGuiKey_V; - case SDLK_w: - return ImGuiKey_W; - case SDLK_x: - return ImGuiKey_X; - case SDLK_y: - return ImGuiKey_Y; - case SDLK_z: - return ImGuiKey_Z; - case SDLK_F1: - return ImGuiKey_F1; - case SDLK_F2: - return ImGuiKey_F2; - case SDLK_F3: - return ImGuiKey_F3; - case SDLK_F4: - return ImGuiKey_F4; - case SDLK_F5: - return ImGuiKey_F5; - case SDLK_F6: - return ImGuiKey_F6; - case SDLK_F7: - return ImGuiKey_F7; - case SDLK_F8: - return ImGuiKey_F8; - case SDLK_F9: - return ImGuiKey_F9; - case SDLK_F10: - return ImGuiKey_F10; - case SDLK_F11: - return ImGuiKey_F11; - case SDLK_F12: - return ImGuiKey_F12; - } - return ImGuiKey_None; -} - -static void ImGui_ImplSDL2_UpdateKeyModifiers(SDL_Keymod sdl_key_mods) -{ - ImGuiIO &io = ImGui::GetIO(); - io.AddKeyEvent(ImGuiMod_Ctrl, (sdl_key_mods & KMOD_CTRL) != 0); - io.AddKeyEvent(ImGuiMod_Shift, (sdl_key_mods & KMOD_SHIFT) != 0); - io.AddKeyEvent(ImGuiMod_Alt, (sdl_key_mods & KMOD_ALT) != 0); - io.AddKeyEvent(ImGuiMod_Super, (sdl_key_mods & KMOD_GUI) != 0); -} - -// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. -// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite -// your copy of the mouse data. -// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or -// clear/overwrite your copy of the keyboard data. Generally you may always pass all inputs to dear imgui, and hide them -// from your application based on those two flags. If you have multiple SDL events and some of them are not meant to be -// used by dear imgui, you may need to filter events based on their windowID field. -bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event *event) -{ - ImGuiIO &io = ImGui::GetIO(); - ImGui_ImplSDL2_Data *bd = ImGui_ImplSDL2_GetBackendData(); - - switch (event->type) - { - case SDL_MOUSEMOTION: { - ImVec2 mouse_pos((float)event->motion.x, (float)event->motion.y); - if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) - { - int window_x, window_y; - SDL_GetWindowPosition(SDL_GetWindowFromID(event->motion.windowID), &window_x, &window_y); - mouse_pos.x += window_x; - mouse_pos.y += window_y; - } - io.AddMouseSourceEvent(event->motion.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen - : ImGuiMouseSource_Mouse); - io.AddMousePosEvent(mouse_pos.x, mouse_pos.y); - return true; - } - case SDL_MOUSEWHEEL: { - // IMGUI_DEBUG_LOG("wheel %.2f %.2f, precise %.2f %.2f\n", (float)event->wheel.x, (float)event->wheel.y, - // event->wheel.preciseX, event->wheel.preciseY); -#if SDL_VERSION_ATLEAST(2, 0, 18) // If this fails to compile on Emscripten: update to latest Emscripten! - float wheel_x = -event->wheel.preciseX; - float wheel_y = event->wheel.preciseY; -#else - float wheel_x = -(float)event->wheel.x; - float wheel_y = (float)event->wheel.y; -#endif -#ifdef __EMSCRIPTEN__ - wheel_x /= 100.0f; -#endif - io.AddMouseSourceEvent(event->wheel.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen - : ImGuiMouseSource_Mouse); - io.AddMouseWheelEvent(wheel_x, wheel_y); - return true; - } - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: { - int mouse_button = -1; - if (event->button.button == SDL_BUTTON_LEFT) - { - mouse_button = 0; - } - if (event->button.button == SDL_BUTTON_RIGHT) - { - mouse_button = 1; - } - if (event->button.button == SDL_BUTTON_MIDDLE) - { - mouse_button = 2; - } - if (event->button.button == SDL_BUTTON_X1) - { - mouse_button = 3; - } - if (event->button.button == SDL_BUTTON_X2) - { - mouse_button = 4; - } - if (mouse_button == -1) - break; - io.AddMouseSourceEvent(event->button.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen - : ImGuiMouseSource_Mouse); - io.AddMouseButtonEvent(mouse_button, (event->type == SDL_MOUSEBUTTONDOWN)); - bd->MouseButtonsDown = (event->type == SDL_MOUSEBUTTONDOWN) ? (bd->MouseButtonsDown | (1 << mouse_button)) - : (bd->MouseButtonsDown & ~(1 << mouse_button)); - return true; - } - case SDL_TEXTINPUT: { - io.AddInputCharactersUTF8(event->text.text); - return true; - } - case SDL_KEYDOWN: - case SDL_KEYUP: { - ImGui_ImplSDL2_UpdateKeyModifiers((SDL_Keymod)event->key.keysym.mod); - ImGuiKey key = ImGui_ImplSDL2_KeycodeToImGuiKey(event->key.keysym.sym); - io.AddKeyEvent(key, (event->type == SDL_KEYDOWN)); - io.SetKeyEventNativeData(key, event->key.keysym.sym, event->key.keysym.scancode, - event->key.keysym.scancode); // To support legacy indexing (<1.87 user code). Legacy - // backend uses SDLK_*** as indices to IsKeyXXX() functions. - return true; - } -#if SDL_HAS_DISPLAY_EVENT - case SDL_DISPLAYEVENT: { - // 2.0.26 has SDL_DISPLAYEVENT_CONNECTED/SDL_DISPLAYEVENT_DISCONNECTED/SDL_DISPLAYEVENT_ORIENTATION, - // so change of DPI/Scaling are not reflected in this event. (SDL3 has it) - bd->WantUpdateMonitors = true; - return true; - } -#endif - case SDL_WINDOWEVENT: { - // - When capturing mouse, SDL will send a bunch of conflicting LEAVE/ENTER event on every mouse move, but the - // final ENTER tends to be right. - // - However we won't get a correct LEAVE event for a captured window. - // - In some cases, when detaching a window from main viewport SDL may send SDL_WINDOWEVENT_ENTER one frame too - // late, - // causing SDL_WINDOWEVENT_LEAVE on previous frame to interrupt drag operation by clear mouse position. This is - // why we delay process the SDL_WINDOWEVENT_LEAVE events by one frame. See issue #5012 for details. - Uint8 window_event = event->window.event; - if (window_event == SDL_WINDOWEVENT_ENTER) - { - bd->MouseWindowID = event->window.windowID; - bd->PendingMouseLeaveFrame = 0; - } - if (window_event == SDL_WINDOWEVENT_LEAVE) - bd->PendingMouseLeaveFrame = ImGui::GetFrameCount() + 1; - if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED) - io.AddFocusEvent(true); - else if (window_event == SDL_WINDOWEVENT_FOCUS_LOST) - io.AddFocusEvent(false); - if (window_event == SDL_WINDOWEVENT_CLOSE || window_event == SDL_WINDOWEVENT_MOVED || - window_event == SDL_WINDOWEVENT_RESIZED) - if (ImGuiViewport *viewport = - ImGui::FindViewportByPlatformHandle((void *)SDL_GetWindowFromID(event->window.windowID))) - { - if (window_event == SDL_WINDOWEVENT_CLOSE) - viewport->PlatformRequestClose = true; - if (window_event == SDL_WINDOWEVENT_MOVED) - viewport->PlatformRequestMove = true; - if (window_event == SDL_WINDOWEVENT_RESIZED) - viewport->PlatformRequestResize = true; - return true; - } - return true; - } - } - return false; -} - -static bool ImGui_ImplSDL2_Init(SDL_Window *window, SDL_Renderer *renderer, void *sdl_gl_context) -{ - ImGuiIO &io = ImGui::GetIO(); - IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!"); - - // Check and store if we are on a SDL backend that supports global mouse position - // ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list) - bool mouse_can_use_global_state = false; -#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE - const char *sdl_backend = SDL_GetCurrentVideoDriver(); - const char *global_mouse_whitelist[] = {"windows", "cocoa", "x11", "DIVE", "VMAN"}; - for (int n = 0; n < IM_ARRAYSIZE(global_mouse_whitelist); n++) - if (strncmp(sdl_backend, global_mouse_whitelist[n], strlen(global_mouse_whitelist[n])) == 0) - mouse_can_use_global_state = true; -#endif - - // Setup backend capabilities flags - ImGui_ImplSDL2_Data *bd = IM_NEW(ImGui_ImplSDL2_Data)(); - io.BackendPlatformUserData = (void *)bd; - io.BackendPlatformName = "imgui_impl_sdl2"; - io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) - io.BackendFlags |= - ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) - if (mouse_can_use_global_state) - io.BackendFlags |= - ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional) - - bd->Window = window; - bd->Renderer = renderer; - - // SDL on Linux/OSX doesn't report events for unfocused windows (see https://github.com/ocornut/imgui/issues/4960) - // We will use 'MouseCanReportHoveredViewport' to set 'ImGuiBackendFlags_HasMouseHoveredViewport' dynamically each - // frame. - bd->MouseCanUseGlobalState = mouse_can_use_global_state; -#ifndef __APPLE__ - bd->MouseCanReportHoveredViewport = bd->MouseCanUseGlobalState; -#else - bd->MouseCanReportHoveredViewport = false; -#endif - bd->WantUpdateMonitors = true; - - io.SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplSDL2_GetClipboardText; - io.ClipboardUserData = nullptr; - io.SetPlatformImeDataFn = ImGui_ImplSDL2_SetPlatformImeData; - - // Load mouse cursors - bd->MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); - bd->MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); - bd->MouseCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); - bd->MouseCursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); - bd->MouseCursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); - bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); - bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE); - bd->MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND); - bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO); - - // Set platform dependent data in viewport - // Our mouse update function expect PlatformHandle to be filled for the main viewport - ImGuiViewport *main_viewport = ImGui::GetMainViewport(); - main_viewport->PlatformHandle = (void *)window; - main_viewport->PlatformHandleRaw = nullptr; - SDL_SysWMinfo info; - SDL_VERSION(&info.version); - if (SDL_GetWindowWMInfo(window, &info)) - { -#if defined(SDL_VIDEO_DRIVER_WINDOWS) - main_viewport->PlatformHandleRaw = (void *)info.info.win.window; -#elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA) - main_viewport->PlatformHandleRaw = (void *)info.info.cocoa.window; -#endif - } - - // From 2.0.5: Set SDL hint to receive mouse click events on window focus, otherwise SDL doesn't emit the event. - // Without this, when clicking to gain focus, our widgets wouldn't activate even though they showed as hovered. - // (This is unfortunately a global SDL setting, so enabling it might have a side-effect on your application. - // It is unlikely to make a difference, but if your app absolutely needs to ignore the initial on-focus click: - // you can ignore SDL_MOUSEBUTTONDOWN events coming right after a SDL_WINDOWEVENT_FOCUS_GAINED) -#ifdef SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH - SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); -#endif - - // From 2.0.18: Enable native IME. - // IMPORTANT: This is used at the time of SDL_CreateWindow() so this will only affects secondary windows, if any. - // For the main window to be affected, your application needs to call this manually before calling SDL_CreateWindow(). -#ifdef SDL_HINT_IME_SHOW_UI - SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1"); -#endif - - // From 2.0.22: Disable auto-capture, this is preventing drag and drop across multiple windows (see #5710) -#ifdef SDL_HINT_MOUSE_AUTO_CAPTURE - SDL_SetHint(SDL_HINT_MOUSE_AUTO_CAPTURE, "0"); -#endif - - // We need SDL_CaptureMouse(), SDL_GetGlobalMouseState() from SDL 2.0.4+ to support multiple viewports. - // We left the call to ImGui_ImplSDL2_InitPlatformInterface() outside of #ifdef to avoid unused-function warnings. - if ((io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) && (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports)) - ImGui_ImplSDL2_InitPlatformInterface(window, sdl_gl_context); - - return true; -} - -bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window *window, void *sdl_gl_context) -{ - return ImGui_ImplSDL2_Init(window, nullptr, sdl_gl_context); -} - -bool ImGui_ImplSDL2_InitForVulkan(SDL_Window *window) -{ -#if !SDL_HAS_VULKAN - IM_ASSERT(0 && "Unsupported"); -#endif - if (!ImGui_ImplSDL2_Init(window, nullptr, nullptr)) - return false; - ImGui_ImplSDL2_Data *bd = ImGui_ImplSDL2_GetBackendData(); - bd->UseVulkan = true; - return true; -} - -bool ImGui_ImplSDL2_InitForD3D(SDL_Window *window) -{ -#if !defined(_WIN32) - IM_ASSERT(0 && "Unsupported"); -#endif - return ImGui_ImplSDL2_Init(window, nullptr, nullptr); -} - -bool ImGui_ImplSDL2_InitForMetal(SDL_Window *window) -{ - return ImGui_ImplSDL2_Init(window, nullptr, nullptr); -} - -bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window *window, SDL_Renderer *renderer) -{ - return ImGui_ImplSDL2_Init(window, renderer, nullptr); -} - -void ImGui_ImplSDL2_Shutdown() -{ - ImGui_ImplSDL2_Data *bd = ImGui_ImplSDL2_GetBackendData(); - IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?"); - ImGuiIO &io = ImGui::GetIO(); - - ImGui_ImplSDL2_ShutdownPlatformInterface(); - - if (bd->ClipboardTextData) - SDL_free(bd->ClipboardTextData); - for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++) - SDL_FreeCursor(bd->MouseCursors[cursor_n]); - bd->LastMouseCursor = nullptr; - - io.BackendPlatformName = nullptr; - io.BackendPlatformUserData = nullptr; - io.BackendFlags &= - ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | - ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport); - IM_DELETE(bd); -} - -// This code is incredibly messy because some of the functions we need for full viewport support are not available in -// SDL < 2.0.4. -static void ImGui_ImplSDL2_UpdateMouseData() -{ - ImGui_ImplSDL2_Data *bd = ImGui_ImplSDL2_GetBackendData(); - ImGuiIO &io = ImGui::GetIO(); - - // We forward mouse input when hovered or captured (via SDL_MOUSEMOTION) or when focused (below) -#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE - // SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. - // trigger other operations outside - SDL_CaptureMouse((bd->MouseButtonsDown != 0) ? SDL_TRUE : SDL_FALSE); - SDL_Window *focused_window = SDL_GetKeyboardFocus(); - const bool is_app_focused = - (focused_window && (bd->Window == focused_window || ImGui::FindViewportByPlatformHandle((void *)focused_window))); -#else - SDL_Window *focused_window = bd->Window; - const bool is_app_focused = (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_INPUT_FOCUS) != - 0; // SDL 2.0.3 and non-windowed systems: single-viewport only -#endif - - if (is_app_focused) - { - // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when - // ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) - if (io.WantSetMousePos) - { -#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE - if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) - SDL_WarpMouseGlobal((int)io.MousePos.x, (int)io.MousePos.y); - else -#endif - SDL_WarpMouseInWindow(bd->Window, (int)io.MousePos.x, (int)io.MousePos.y); - } - - // (Optional) Fallback to provide mouse position when focused (SDL_MOUSEMOTION already provides this when hovered or - // captured) - if (bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0) - { - // Single-viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on - // the upper-left corner of the app window) Multi-viewport mode: mouse position in OS absolute coordinates - // (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor) - int mouse_x, mouse_y, window_x, window_y; - SDL_GetGlobalMouseState(&mouse_x, &mouse_y); - if (!(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)) - { - SDL_GetWindowPosition(focused_window, &window_x, &window_y); - mouse_x -= window_x; - mouse_y -= window_y; - } - io.AddMousePosEvent((float)mouse_x, (float)mouse_y); - } - } - - // (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is - // hovering. If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear imGui will ignore this field - // and infer the information using its flawed heuristic. - // - [!] SDL backend does NOT correctly ignore viewports with the _NoInputs flag. - // Some backend are not able to handle that correctly. If a backend report an hovered viewport that has the - // _NoInputs flag (e.g. when dragging a window for docking, the viewport has the _NoInputs flag in order to - // allow us to find the viewport under), then Dear ImGui is forced to ignore the value reported by the backend, - // and use its flawed heuristic to guess the viewport behind. - // - [X] SDL backend correctly reports this regardless of another viewport behind focused and dragged from (we need - // this to find a useful drag and drop target). - if (io.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport) - { - ImGuiID mouse_viewport_id = 0; - if (SDL_Window *sdl_mouse_window = SDL_GetWindowFromID(bd->MouseWindowID)) - if (ImGuiViewport *mouse_viewport = ImGui::FindViewportByPlatformHandle((void *)sdl_mouse_window)) - mouse_viewport_id = mouse_viewport->ID; - io.AddMouseViewportEvent(mouse_viewport_id); - } -} - -static void ImGui_ImplSDL2_UpdateMouseCursor() -{ - ImGuiIO &io = ImGui::GetIO(); - if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) - return; - ImGui_ImplSDL2_Data *bd = ImGui_ImplSDL2_GetBackendData(); - - ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor(); - if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None) - { - // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor - SDL_ShowCursor(SDL_FALSE); - } - else - { - // Show OS mouse cursor - SDL_Cursor *expected_cursor = - bd->MouseCursors[imgui_cursor] ? bd->MouseCursors[imgui_cursor] : bd->MouseCursors[ImGuiMouseCursor_Arrow]; - if (bd->LastMouseCursor != expected_cursor) - { - SDL_SetCursor(expected_cursor); // SDL function doesn't have an early out (see #6113) - bd->LastMouseCursor = expected_cursor; - } - SDL_ShowCursor(SDL_TRUE); - } -} - -static void ImGui_ImplSDL2_UpdateGamepads() -{ - ImGuiIO &io = ImGui::GetIO(); - if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == - 0) // FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs. - return; - - // Get gamepad - io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; - SDL_GameController *game_controller = SDL_GameControllerOpen(0); - if (!game_controller) - return; - io.BackendFlags |= ImGuiBackendFlags_HasGamepad; - -// Update gamepad inputs -#define IM_SATURATE(V) (V < 0.0f ? 0.0f : V > 1.0f ? 1.0f : V) -#define MAP_BUTTON(KEY_NO, BUTTON_NO) \ - { \ - io.AddKeyEvent(KEY_NO, SDL_GameControllerGetButton(game_controller, BUTTON_NO) != 0); \ - } -#define MAP_ANALOG(KEY_NO, AXIS_NO, V0, V1) \ - { \ - float vn = (float)(SDL_GameControllerGetAxis(game_controller, AXIS_NO) - V0) / (float)(V1 - V0); \ - vn = IM_SATURATE(vn); \ - io.AddKeyAnalogEvent(KEY_NO, vn > 0.1f, vn); \ - } - const int thumb_dead_zone = 8000; // SDL_gamecontroller.h suggests using this value. - MAP_BUTTON(ImGuiKey_GamepadStart, SDL_CONTROLLER_BUTTON_START); - MAP_BUTTON(ImGuiKey_GamepadBack, SDL_CONTROLLER_BUTTON_BACK); - MAP_BUTTON(ImGuiKey_GamepadFaceLeft, SDL_CONTROLLER_BUTTON_X); // Xbox X, PS Square - MAP_BUTTON(ImGuiKey_GamepadFaceRight, SDL_CONTROLLER_BUTTON_B); // Xbox B, PS Circle - MAP_BUTTON(ImGuiKey_GamepadFaceUp, SDL_CONTROLLER_BUTTON_Y); // Xbox Y, PS Triangle - MAP_BUTTON(ImGuiKey_GamepadFaceDown, SDL_CONTROLLER_BUTTON_A); // Xbox A, PS Cross - MAP_BUTTON(ImGuiKey_GamepadDpadLeft, SDL_CONTROLLER_BUTTON_DPAD_LEFT); - MAP_BUTTON(ImGuiKey_GamepadDpadRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT); - MAP_BUTTON(ImGuiKey_GamepadDpadUp, SDL_CONTROLLER_BUTTON_DPAD_UP); - MAP_BUTTON(ImGuiKey_GamepadDpadDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN); - MAP_BUTTON(ImGuiKey_GamepadL1, SDL_CONTROLLER_BUTTON_LEFTSHOULDER); - MAP_BUTTON(ImGuiKey_GamepadR1, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); - MAP_ANALOG(ImGuiKey_GamepadL2, SDL_CONTROLLER_AXIS_TRIGGERLEFT, 0.0f, 32767); - MAP_ANALOG(ImGuiKey_GamepadR2, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, 0.0f, 32767); - MAP_BUTTON(ImGuiKey_GamepadL3, SDL_CONTROLLER_BUTTON_LEFTSTICK); - MAP_BUTTON(ImGuiKey_GamepadR3, SDL_CONTROLLER_BUTTON_RIGHTSTICK); - MAP_ANALOG(ImGuiKey_GamepadLStickLeft, SDL_CONTROLLER_AXIS_LEFTX, -thumb_dead_zone, -32768); - MAP_ANALOG(ImGuiKey_GamepadLStickRight, SDL_CONTROLLER_AXIS_LEFTX, +thumb_dead_zone, +32767); - MAP_ANALOG(ImGuiKey_GamepadLStickUp, SDL_CONTROLLER_AXIS_LEFTY, -thumb_dead_zone, -32768); - MAP_ANALOG(ImGuiKey_GamepadLStickDown, SDL_CONTROLLER_AXIS_LEFTY, +thumb_dead_zone, +32767); - MAP_ANALOG(ImGuiKey_GamepadRStickLeft, SDL_CONTROLLER_AXIS_RIGHTX, -thumb_dead_zone, -32768); - MAP_ANALOG(ImGuiKey_GamepadRStickRight, SDL_CONTROLLER_AXIS_RIGHTX, +thumb_dead_zone, +32767); - MAP_ANALOG(ImGuiKey_GamepadRStickUp, SDL_CONTROLLER_AXIS_RIGHTY, -thumb_dead_zone, -32768); - MAP_ANALOG(ImGuiKey_GamepadRStickDown, SDL_CONTROLLER_AXIS_RIGHTY, +thumb_dead_zone, +32767); -#undef MAP_BUTTON -#undef MAP_ANALOG -} - -// FIXME: Note that doesn't update with DPI/Scaling change only as SDL2 doesn't have an event for it (SDL3 has). -static void ImGui_ImplSDL2_UpdateMonitors() -{ - ImGui_ImplSDL2_Data *bd = ImGui_ImplSDL2_GetBackendData(); - ImGuiPlatformIO &platform_io = ImGui::GetPlatformIO(); - platform_io.Monitors.resize(0); - bd->WantUpdateMonitors = false; - int display_count = SDL_GetNumVideoDisplays(); - for (int n = 0; n < display_count; n++) - { - // Warning: the validity of monitor DPI information on Windows depends on the application DPI awareness settings, - // which generally needs to be set in the manifest or at runtime. - ImGuiPlatformMonitor monitor; - SDL_Rect r; - SDL_GetDisplayBounds(n, &r); - monitor.MainPos = monitor.WorkPos = ImVec2((float)r.x, (float)r.y); - monitor.MainSize = monitor.WorkSize = ImVec2((float)r.w, (float)r.h); -#if SDL_HAS_USABLE_DISPLAY_BOUNDS - SDL_GetDisplayUsableBounds(n, &r); - monitor.WorkPos = ImVec2((float)r.x, (float)r.y); - monitor.WorkSize = ImVec2((float)r.w, (float)r.h); -#endif -#if SDL_HAS_PER_MONITOR_DPI - // FIXME-VIEWPORT: On MacOS SDL reports actual monitor DPI scale, ignoring OS configuration. We may want to set - // DpiScale to cocoa_window.backingScaleFactor here. - float dpi = 0.0f; - if (!SDL_GetDisplayDPI(n, &dpi, nullptr, nullptr)) - monitor.DpiScale = dpi / 96.0f; -#endif - monitor.PlatformHandle = (void *)(intptr_t)n; - platform_io.Monitors.push_back(monitor); - } -} - -void ImGui_ImplSDL2_NewFrame() -{ - ImGui_ImplSDL2_Data *bd = ImGui_ImplSDL2_GetBackendData(); - IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplSDL2_Init()?"); - ImGuiIO &io = ImGui::GetIO(); - - // Setup display size (every frame to accommodate for window resizing) - int w, h; - int display_w, display_h; - SDL_GetWindowSize(bd->Window, &w, &h); - if (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_MINIMIZED) - w = h = 0; - if (bd->Renderer != nullptr) - SDL_GetRendererOutputSize(bd->Renderer, &display_w, &display_h); - else - SDL_GL_GetDrawableSize(bd->Window, &display_w, &display_h); - io.DisplaySize = ImVec2((float)w, (float)h); - if (w > 0 && h > 0) - io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h); - - // Update monitors - if (bd->WantUpdateMonitors) - ImGui_ImplSDL2_UpdateMonitors(); - - // Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution) - // (Accept SDL_GetPerformanceCounter() not returning a monotonically increasing value. Happens in VMs and Emscripten, - // see #6189, #6114, #3644) - static Uint64 frequency = SDL_GetPerformanceFrequency(); - Uint64 current_time = SDL_GetPerformanceCounter(); - if (current_time <= bd->Time) - current_time = bd->Time + 1; - io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f); - bd->Time = current_time; - - if (bd->PendingMouseLeaveFrame && bd->PendingMouseLeaveFrame >= ImGui::GetFrameCount() && bd->MouseButtonsDown == 0) - { - bd->MouseWindowID = 0; - bd->PendingMouseLeaveFrame = 0; - io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); - } - - // Our io.AddMouseViewportEvent() calls will only be valid when not capturing. - // Technically speaking testing for 'bd->MouseButtonsDown == 0' would be more rygorous, but testing for payload - // reduces noise and potential side-effects. - if (bd->MouseCanReportHoveredViewport && ImGui::GetDragDropPayload() == nullptr) - io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; - else - io.BackendFlags &= ~ImGuiBackendFlags_HasMouseHoveredViewport; - - ImGui_ImplSDL2_UpdateMouseData(); - ImGui_ImplSDL2_UpdateMouseCursor(); - - // Update game controllers (if enabled and available) - ImGui_ImplSDL2_UpdateGamepads(); -} - -//-------------------------------------------------------------------------------------------------------- -// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT -// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports -// simultaneously. If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you -// completely ignore this section first.. -//-------------------------------------------------------------------------------------------------------- - -// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our backend -// data. -struct ImGui_ImplSDL2_ViewportData -{ - SDL_Window *Window; - Uint32 WindowID; - bool WindowOwned; - SDL_GLContext GLContext; - - ImGui_ImplSDL2_ViewportData() - { - Window = nullptr; - WindowID = 0; - WindowOwned = false; - GLContext = nullptr; - } - ~ImGui_ImplSDL2_ViewportData() - { - IM_ASSERT(Window == nullptr && GLContext == nullptr); - } -}; - -static void ImGui_ImplSDL2_CreateWindow(ImGuiViewport *viewport) -{ - ImGui_ImplSDL2_Data *bd = ImGui_ImplSDL2_GetBackendData(); - ImGui_ImplSDL2_ViewportData *vd = IM_NEW(ImGui_ImplSDL2_ViewportData)(); - viewport->PlatformUserData = vd; - - ImGuiViewport *main_viewport = ImGui::GetMainViewport(); - ImGui_ImplSDL2_ViewportData *main_viewport_data = (ImGui_ImplSDL2_ViewportData *)main_viewport->PlatformUserData; - - // Share GL resources with main context - bool use_opengl = (main_viewport_data->GLContext != nullptr); - SDL_GLContext backup_context = nullptr; - if (use_opengl) - { - backup_context = SDL_GL_GetCurrentContext(); - SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1); - SDL_GL_MakeCurrent(main_viewport_data->Window, main_viewport_data->GLContext); - } - - Uint32 sdl_flags = 0; - sdl_flags |= use_opengl ? SDL_WINDOW_OPENGL : (bd->UseVulkan ? SDL_WINDOW_VULKAN : 0); - sdl_flags |= SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_ALLOW_HIGHDPI; - sdl_flags |= SDL_WINDOW_HIDDEN; - sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? SDL_WINDOW_BORDERLESS : 0; - sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? 0 : SDL_WINDOW_RESIZABLE; -#if !defined(_WIN32) - // See SDL hack in ImGui_ImplSDL2_ShowWindow(). - sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon) ? SDL_WINDOW_SKIP_TASKBAR : 0; -#endif -#if SDL_HAS_ALWAYS_ON_TOP - sdl_flags |= (viewport->Flags & ImGuiViewportFlags_TopMost) ? SDL_WINDOW_ALWAYS_ON_TOP : 0; -#endif - vd->Window = SDL_CreateWindow("No Title Yet", (int)viewport->Pos.x, (int)viewport->Pos.y, (int)viewport->Size.x, - (int)viewport->Size.y, sdl_flags); - vd->WindowOwned = true; - if (use_opengl) - { - vd->GLContext = SDL_GL_CreateContext(vd->Window); - SDL_GL_SetSwapInterval(0); - } - if (use_opengl && backup_context) - SDL_GL_MakeCurrent(vd->Window, backup_context); - - viewport->PlatformHandle = (void *)vd->Window; - viewport->PlatformHandleRaw = nullptr; - SDL_SysWMinfo info; - SDL_VERSION(&info.version); - if (SDL_GetWindowWMInfo(vd->Window, &info)) - { -#if defined(SDL_VIDEO_DRIVER_WINDOWS) - viewport->PlatformHandleRaw = info.info.win.window; -#elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA) - viewport->PlatformHandleRaw = (void *)info.info.cocoa.window; -#endif - } -} - -static void ImGui_ImplSDL2_DestroyWindow(ImGuiViewport *viewport) -{ - if (ImGui_ImplSDL2_ViewportData *vd = (ImGui_ImplSDL2_ViewportData *)viewport->PlatformUserData) - { - if (vd->GLContext && vd->WindowOwned) - SDL_GL_DeleteContext(vd->GLContext); - if (vd->Window && vd->WindowOwned) - SDL_DestroyWindow(vd->Window); - vd->GLContext = nullptr; - vd->Window = nullptr; - IM_DELETE(vd); - } - viewport->PlatformUserData = viewport->PlatformHandle = nullptr; -} - -static void ImGui_ImplSDL2_ShowWindow(ImGuiViewport *viewport) -{ - ImGui_ImplSDL2_ViewportData *vd = (ImGui_ImplSDL2_ViewportData *)viewport->PlatformUserData; -#if defined(_WIN32) - HWND hwnd = (HWND)viewport->PlatformHandleRaw; - - // SDL hack: Hide icon from task bar - // Note: SDL 2.0.6+ has a SDL_WINDOW_SKIP_TASKBAR flag which is supported under Windows but the way it create the - // window breaks our seamless transition. - if (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon) - { - LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE); - ex_style &= ~WS_EX_APPWINDOW; - ex_style |= WS_EX_TOOLWINDOW; - ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style); - } - - // SDL hack: SDL always activate/focus windows :/ - if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing) - { - ::ShowWindow(hwnd, SW_SHOWNA); - return; - } -#endif - - SDL_ShowWindow(vd->Window); -} - -static ImVec2 ImGui_ImplSDL2_GetWindowPos(ImGuiViewport *viewport) -{ - ImGui_ImplSDL2_ViewportData *vd = (ImGui_ImplSDL2_ViewportData *)viewport->PlatformUserData; - int x = 0, y = 0; - SDL_GetWindowPosition(vd->Window, &x, &y); - return ImVec2((float)x, (float)y); -} - -static void ImGui_ImplSDL2_SetWindowPos(ImGuiViewport *viewport, ImVec2 pos) -{ - ImGui_ImplSDL2_ViewportData *vd = (ImGui_ImplSDL2_ViewportData *)viewport->PlatformUserData; - SDL_SetWindowPosition(vd->Window, (int)pos.x, (int)pos.y); -} - -static ImVec2 ImGui_ImplSDL2_GetWindowSize(ImGuiViewport *viewport) -{ - ImGui_ImplSDL2_ViewportData *vd = (ImGui_ImplSDL2_ViewportData *)viewport->PlatformUserData; - int w = 0, h = 0; - SDL_GetWindowSize(vd->Window, &w, &h); - return ImVec2((float)w, (float)h); -} - -static void ImGui_ImplSDL2_SetWindowSize(ImGuiViewport *viewport, ImVec2 size) -{ - ImGui_ImplSDL2_ViewportData *vd = (ImGui_ImplSDL2_ViewportData *)viewport->PlatformUserData; - SDL_SetWindowSize(vd->Window, (int)size.x, (int)size.y); -} - -static void ImGui_ImplSDL2_SetWindowTitle(ImGuiViewport *viewport, const char *title) -{ - ImGui_ImplSDL2_ViewportData *vd = (ImGui_ImplSDL2_ViewportData *)viewport->PlatformUserData; - SDL_SetWindowTitle(vd->Window, title); -} - -#if SDL_HAS_WINDOW_ALPHA -static void ImGui_ImplSDL2_SetWindowAlpha(ImGuiViewport *viewport, float alpha) -{ - ImGui_ImplSDL2_ViewportData *vd = (ImGui_ImplSDL2_ViewportData *)viewport->PlatformUserData; - SDL_SetWindowOpacity(vd->Window, alpha); -} -#endif - -static void ImGui_ImplSDL2_SetWindowFocus(ImGuiViewport *viewport) -{ - ImGui_ImplSDL2_ViewportData *vd = (ImGui_ImplSDL2_ViewportData *)viewport->PlatformUserData; - SDL_RaiseWindow(vd->Window); -} - -static bool ImGui_ImplSDL2_GetWindowFocus(ImGuiViewport *viewport) -{ - ImGui_ImplSDL2_ViewportData *vd = (ImGui_ImplSDL2_ViewportData *)viewport->PlatformUserData; - return (SDL_GetWindowFlags(vd->Window) & SDL_WINDOW_INPUT_FOCUS) != 0; -} - -static bool ImGui_ImplSDL2_GetWindowMinimized(ImGuiViewport *viewport) -{ - ImGui_ImplSDL2_ViewportData *vd = (ImGui_ImplSDL2_ViewportData *)viewport->PlatformUserData; - return (SDL_GetWindowFlags(vd->Window) & SDL_WINDOW_MINIMIZED) != 0; -} - -static void ImGui_ImplSDL2_RenderWindow(ImGuiViewport *viewport, void *) -{ - ImGui_ImplSDL2_ViewportData *vd = (ImGui_ImplSDL2_ViewportData *)viewport->PlatformUserData; - if (vd->GLContext) - SDL_GL_MakeCurrent(vd->Window, vd->GLContext); -} - -static void ImGui_ImplSDL2_SwapBuffers(ImGuiViewport *viewport, void *) -{ - ImGui_ImplSDL2_ViewportData *vd = (ImGui_ImplSDL2_ViewportData *)viewport->PlatformUserData; - if (vd->GLContext) - { - SDL_GL_MakeCurrent(vd->Window, vd->GLContext); - SDL_GL_SwapWindow(vd->Window); - } -} - -// Vulkan support (the Vulkan renderer needs to call a platform-side support function to create the surface) -// SDL is graceful enough to _not_ need so we can safely include this. -#if SDL_HAS_VULKAN -# include -static int ImGui_ImplSDL2_CreateVkSurface(ImGuiViewport *viewport, ImU64 vk_instance, const void *vk_allocator, - ImU64 *out_vk_surface) -{ - ImGui_ImplSDL2_ViewportData *vd = (ImGui_ImplSDL2_ViewportData *)viewport->PlatformUserData; - (void)vk_allocator; - SDL_bool ret = SDL_Vulkan_CreateSurface(vd->Window, (VkInstance)vk_instance, (VkSurfaceKHR *)out_vk_surface); - return ret ? 0 : 1; // ret ? VK_SUCCESS : VK_NOT_READY -} -#endif // SDL_HAS_VULKAN - -static void ImGui_ImplSDL2_InitPlatformInterface(SDL_Window *window, void *sdl_gl_context) -{ - // Register platform interface (will be coupled with a renderer interface) - ImGuiPlatformIO &platform_io = ImGui::GetPlatformIO(); - platform_io.Platform_CreateWindow = ImGui_ImplSDL2_CreateWindow; - platform_io.Platform_DestroyWindow = ImGui_ImplSDL2_DestroyWindow; - platform_io.Platform_ShowWindow = ImGui_ImplSDL2_ShowWindow; - platform_io.Platform_SetWindowPos = ImGui_ImplSDL2_SetWindowPos; - platform_io.Platform_GetWindowPos = ImGui_ImplSDL2_GetWindowPos; - platform_io.Platform_SetWindowSize = ImGui_ImplSDL2_SetWindowSize; - platform_io.Platform_GetWindowSize = ImGui_ImplSDL2_GetWindowSize; - platform_io.Platform_SetWindowFocus = ImGui_ImplSDL2_SetWindowFocus; - platform_io.Platform_GetWindowFocus = ImGui_ImplSDL2_GetWindowFocus; - platform_io.Platform_GetWindowMinimized = ImGui_ImplSDL2_GetWindowMinimized; - platform_io.Platform_SetWindowTitle = ImGui_ImplSDL2_SetWindowTitle; - platform_io.Platform_RenderWindow = ImGui_ImplSDL2_RenderWindow; - platform_io.Platform_SwapBuffers = ImGui_ImplSDL2_SwapBuffers; -#if SDL_HAS_WINDOW_ALPHA - platform_io.Platform_SetWindowAlpha = ImGui_ImplSDL2_SetWindowAlpha; -#endif -#if SDL_HAS_VULKAN - platform_io.Platform_CreateVkSurface = ImGui_ImplSDL2_CreateVkSurface; -#endif - - // Register main window handle (which is owned by the main application, not by us) - // This is mostly for simplicity and consistency, so that our code (e.g. mouse handling etc.) can use same logic for - // main and secondary viewports. - ImGuiViewport *main_viewport = ImGui::GetMainViewport(); - ImGui_ImplSDL2_ViewportData *vd = IM_NEW(ImGui_ImplSDL2_ViewportData)(); - vd->Window = window; - vd->WindowID = SDL_GetWindowID(window); - vd->WindowOwned = false; - vd->GLContext = sdl_gl_context; - main_viewport->PlatformUserData = vd; - main_viewport->PlatformHandle = vd->Window; -} - -static void ImGui_ImplSDL2_ShutdownPlatformInterface() -{ - ImGui::DestroyPlatformWindows(); -} - -#if defined(__clang__) -# pragma clang diagnostic pop -#endif diff --git a/src/backends/imgui_impl_sdl2.h b/src/backends/imgui_impl_sdl2.h deleted file mode 100644 index d6612c6..0000000 --- a/src/backends/imgui_impl_sdl2.h +++ /dev/null @@ -1,46 +0,0 @@ -// dear imgui: Platform Backend for SDL2 -// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) -// (Info: SDL2 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, -// etc.) - -// Implemented features: -// [X] Platform: Clipboard support. -// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen. -// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all -// key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless -// IMGUI_DISABLE_OBSOLETE_KEYIO is set] [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= -// ImGuiConfigFlags_NavEnableGamepad'. [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= -// ImGuiConfigFlags_NoMouseCursorChange'. [X] Platform: Multi-viewport support (multiple windows). Enable with -// 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. -// Missing features: -// [ ] Platform: Multi-viewport + Minimized windows seems to break mouse wheel events (at least under Windows). -// [x] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before -// SDL_CreateWindow()!. - -// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. -// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build -// the backends you need. If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of -// imgui.cpp. Read online: https://github.com/ocornut/imgui/tree/master/docs - -#pragma once -#include "imgui.h" // IMGUI_IMPL_API - -struct SDL_Window; -struct SDL_Renderer; -typedef union SDL_Event SDL_Event; - -IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window *window, void *sdl_gl_context); -IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForVulkan(SDL_Window *window); -IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForD3D(SDL_Window *window); -IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForMetal(SDL_Window *window); -IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window *window, SDL_Renderer *renderer); -IMGUI_IMPL_API void ImGui_ImplSDL2_Shutdown(); -IMGUI_IMPL_API void ImGui_ImplSDL2_NewFrame(); -IMGUI_IMPL_API bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event *event); - -#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS -static inline void ImGui_ImplSDL2_NewFrame(SDL_Window *) -{ - ImGui_ImplSDL2_NewFrame(); -} // 1.84: removed unnecessary parameter -#endif diff --git a/vendor/FeldarianBaseLibrary/.clang-format b/vendor/FeldarianBaseLibrary/.clang-format new file mode 100644 index 0000000..a3e3dc1 --- /dev/null +++ b/vendor/FeldarianBaseLibrary/.clang-format @@ -0,0 +1,15 @@ +--- +BasedOnStyle: Microsoft +IndentCaseLabels: 'true' +IndentPPDirectives: AfterHash +IndentWidth: '2' +IndentWrappedFunctionNames: 'true' +Language: Cpp +PointerAlignment: Right +SortIncludes: 'true' +SpaceBeforeRangeBasedForLoopColon: 'true' +Standard: Auto +TabWidth: '2' +UseTab: Never + +... diff --git a/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 BG.txt b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 BG.txt new file mode 100644 index 0000000..4060a99 --- /dev/null +++ b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 BG.txt @@ -0,0 +1,96 @@ +ПУБЛИЧЕН ЛИЦЕНЗ НА ЕВРОПЕЙСКИЯ СЪЮЗ версия 1.2 +EUPL © Европейски съюз 2007, 2016 + +Настоящият публичен лиценз на Европейския съюз (EUPL) се прилага към произведението (както е определено по-долу), което се предоставя при условията на този лиценз. Всяко ползване на произведението, различно от това, което е позволено от настоящия лиценз, e забранено (до степента, в която такова ползване е предмет на правата на притежателя на авторското право върху произведението). Произведението се предоставя при условията на настоящия лиценз, когато лицензодателят (както е определено по-долу) е поставил следния текст непосредствено след надписа за авторското право върху произведението: + Лицензирано при условията на EUPL +или е изразил по какъвто и да е друг начин своето желание за лицензиране при условията на EUPL. + +1.Определения +Използваните в настоящия лиценз термини имат следното значение: +— „Лицензът“:настоящият лиценз. +— „Оригиналното произведение“:произведението или софтуерът, разпространявани или предоставяни от лицензодателя при условията на настоящия лиценз, налични като изходен и в някои случаи също и като изпълним код. +— „Производни произведения“:произведенията или софтуерът, които могат да бъдат създадени от лицензополучателя на базата на оригиналното произведение или на негови модификации. Този лиценз не определя степента на модификация или на зависимост от оригиналното произведение, необходима за класифициране на произведението като производно произведение; този обхват се определя от Закона за авторското право, приложим в посочената в член 15 държава. +— „Произведението“:оригиналното произведение или неговите производни произведения. +— „Изходен код“:разбираемата за човека форма на произведението, която е най-удобна за изучаване и модифициране от хората. +— „Изпълним код“:всеки код, който в общия случай е компилиран и е предназначен за изпълняване от компютър като програма. +— „Лицензодател“:физическото или юридическото лице, което разпространява или предоставя произведението при условията на лиценза. +— „Сътрудник (сътрудници)“:всяко физическо или юридическо лице, което модифицира произведението, предмет на лиценза, или по друг начин допринася за създаването на производно произведение. +— „Лицензополучателят“ или „Вие“:всяко физическо или юридическо лице, което използва по какъвто и да е начин произведението при условията на лиценза. +— „Разпространение или предоставяне“:всяко действие на продажба, даване, заемане, даване под наем, разпространение, съобщаване, предаване или друг начин за осигуряване на достъпността, в режим онлайн или офлайн, на копия на произведението или осигуряването на достъп до негови съществени функции на което и да е друго физическо или юридическо лице. + +2.Обхват на предоставените от лиценза права +Лицензодателят Ви дава по този начин един световен безвъзмезден лиценз, без изключително право, който може да подлежи на последващи преотстъпвания на лиценза, за да извършвате следното за периода на авторското право върху оригиналното произведение: +— да ползвате произведението при всякакви обстоятелства и за всякаква употреба, +— да възпроизвеждате произведението, +— да модифицирате произведението и да правите производни произведения от него, +— да представяте на обществеността, включително правото да предоставяте на разположение или да показвате и демонстрирате, според случая, произведението или копия от него на обществеността, +— да разпространявате произведението или копия от него, +— да давате произведението или копия от него назаем или под наем, +— да преотстъпвате права върху произведението или върху копия от него. Тези права могат да бъдат упражнявани върху всякакви медии, носители и формати, познати в настоящия момент или изобретени впоследствие, доколкото приложимото право позволява това. В страните, в които се прилага защита на неимуществени права, лицензодателят се отказва да упражнява неимуществените си права до позволената от закона степен, за да може лицензът да бъде използван за изброените по-горе имуществени права. Лицензодателят предоставя на лицензополучателя права за безвъзмездно и неизключително ползване на всеки свой патент до степента, необходима за ползване на правата, които са предоставени върху произведението при условията на настоящия лиценз. + +3.Предоставяне на изходния код +Лицензодателят може да предостави произведението или в неговия изходен код, или като изпълним код. Ако произведението е предоставено в изпълним код, лицензодателят осигурява допълнително машинно четимо копие на изходния код на произведението заедно с всяко копие на произведението, което лицензодателят разпространява, или в приложения към произведението текст, следващ надписа за авторско право, посочва хранилище, където изходният код е свободно и леснодостъпен, докато лицензодателят продължава да разпространява или предоставя произведението. + +4.Ограничения върху авторското право +Нищо в настоящия лиценз няма за цел да лиши лицензополучателя от предимствата на което и да е изключение или ограничение на изключителните права на притежателите на правата върху произведението, на изчерпването на тези права или на което и да е друго приложимо ограничение. + +5.Задължения на лицензополучателя +Предоставянето на упоменатите по-горе права подлежи на някои ограничения и задължения, наложени на лицензополучателя. Тези задължения са следните: +Право на признаване: Лицензополучателят оставя непокътнати всички надписи за авторско право, патент или търговска марка и всички надписи, които се отнасят за лиценза и отказа от гаранции. Лицензополучателят трябва да включи копие от тези надписи и копие от лиценза към всяко копие на произведението, което той разпространява или предоставя. Лицензополучателят трябва да поставя върху всяко производно произведение ясно забележим надпис, от който да е видно, че произведението е било модифицирано, както и датата на модификацията. + +Клауза „свободно от авторски права“: Ако лицензополучателят разпространява или предоставя копия на оригиналното произведение или производни произведения, това разпространение или предоставяне ще се прави съгласно условията на настоящия лиценз или на по-нова версия на настоящия лиценз, освен ако оригиналното произведение се разпространява изрично единствено съгласно настоящата версия на лиценза — например с отбелязване „само EUPL версия 1.2“. Лицензополучателят (станал лицензодател) не може да предлага или налага каквито и да било допълнителни условия по отношение на произведението или производното произведение, които променят или накърняват условията на лиценза. + +Клауза за съвместимост: Ако лицензополучателят разпространява или предоставя производни произведения или копия от тях на базата както на произведението, така и на друго произведение, лицензирано при условията на съвместим лиценз, това разпространение или предоставяне може да се направи при условията на този съвместим лиценз. За целта на настоящата клауза „съвместим лиценз“ означава лиценз, посочен в допълнението към настоящия лиценз. Ако задълженията на лицензополучателя по съвместимия лиценз са в противоречие със задълженията му по настоящия лиценз, то задълженията по съвместимия лиценз са с предимство. + +Предоставяне на изходен код: Когато разпространява или предоставя копия на произведението, лицензополучателят ще осигури машинно четимо копие на изходния код, или ще посочи хранилище, където този изходен код е свободно и леснодостъпен, докато лицензополучателят продължава да разпространява или предоставя произведението. + +Правна защита: Този лиценз не дава разрешение за ползване на търговски имена, търговски марки, марки на продукти или услуги или имена на лицензодателя, с изключение на изискваното за разумното и обичайното ползване при описване на произхода на произведението и възпроизвеждането на съдържанието на надписа за авторско право. + +6.Система на авторство +Първоначалният лицензодател гарантира, че авторските права върху оригиналното произведение, които са преотстъпени в рамките на настоящия лиценз, се притежават от него или са му дадени в рамките на лиценза и че той има правото и пълномощията да предоставя лиценза. Всеки сътрудник гарантира, че авторските права върху модификациите, които той е внесъл в произведението, се притежават от него или са му дадени в рамките на лиценза и че той има правото и пълномощията да предоставя този лиценз. Всеки път, когато Вие приемате условията на лиценза, първоначалният лицензодател и последващите сътрудници Ви предоставят лиценз за техния принос към произведението при условията на настоящия лиценз. + +7.Отказ от гаранции +Произведението представлява продукт в процес на развитие, което непрекъснато се усъвършенства от много сътрудници. То не е завършен продукт и по тази причина може да съдържа дефекти или „бъгове“, присъщи на този тип разработки. По горната причина произведението се предоставя при условията на този лиценз „във вида, в който е“ и без каквито и да било гаранции за него, включително, без изброяването да е изчерпателно, пускане на пазара, пригодност за конкретна цел, липса на дефекти и грешки, точност, ненарушение на правата върху интелектуална собственост, различни от авторското право по член 6 от настоящия лиценз. Този отказ от гаранции е основна част от лиценза и условие за предоставяне на каквито и да било права върху произведението. + +8.Отказ от отговорност +С изключение на случаите на предумишлено недобросъвестно поведение или щети, причинени пряко на физически лица, лицензодателят не е отговорен в никакъв случай за каквито и да било преки или непреки, материални или морални щети от всякакъв вид, произтичащи от лиценза или от използването на произведението, включително, без изброяването да е изчерпателно, щети от загуба на клиенти, спиране на работа, лошо функциониране или спиране на работата на компютъра, загуба на данни или каквато и да е търговска вреда, дори и лицензодателят да е бил предупреден за възможността от такава вреда. Лицензодателят ще бъде обаче отговорен, в рамките на закона, от гледна точка на продуктовата отговорност, доколкото такива законови разпоредби се прилагат във връзка с произведението. + +9.Допълнителни споразумения +Докато разпространявате произведението, Вие можете да сключите допълнително споразумение, като определите задължения или услуги, съвместими с настоящия лиценз. Ако поемате задължения обаче, Вие можете да действате само от свое име и единствено на Ваша отговорност, а не от името на първоначалния лицензодател или на който и да е друг сътрудник, и само при положение че се съгласите да обезщетите, защитите и освободите от отговорност който и да е сътрудник, срещу когото са предявени права поради факта, че Вие сте поели каквито и да било гаранции или допълнителна отговорност. + +10.Приемане на лиценза +Можете да приемете условията на настоящия лиценз чрез кликване върху икона „I agree“ („съгласен съм“), поставена в долния край на прозореца, показващ текста на настоящия лиценз, или чрез потвърждаване на съгласието по всеки друг подобен начин, в съответствие с приложимото право. Кликването върху тази икона изразява ясното и безвъзвратно приемане на настоящия лиценз и всички негови принципи и условия от Ваша страна. По същия начин Вие приемате безвъзвратно настоящия лиценз и всички негови принципи и условия, упражнявайки което и да е от правата, дадени Ви по силата на член 2 от настоящия лиценз, като например ползване на произведението, създаване от Вас на производно произведение от него или разпространение или предоставяне от Вас на произведението или на копие от него. + +11.Информация за обществеността +В случай на каквото и да е разпространение или предоставяне от Вас на произведението чрез електронно средство за комуникация (например чрез предложение за дистанционно изтегляне), чрез канала или медията за разпространение (например уебсайт) на обществеността трябва да се предостави най-малко изискваната от приложимото право информация по отношение на лицензодателя, лиценза и начина, по който може да бъде получен достъп до лиценза, и той може да бъде сключен, съхранен и възпроизведен от лицензополучателя. + +12.Прекратяване на лиценза +Лицензът и предоставените от него права ще се прекратят автоматично при всяко нарушение на условията на лиценза от страна на лицензополучателя. Това събитие няма да прекрати правата върху лицензите на което и да е лице, което е получило произведението от лицензополучателя по силата на лиценза, при положение че това лице спазва напълно условията на лиценза. + +13.Други +Без да засяга разпоредбите на член 9 по-горе, лицензът представлява цялостното споразумение между страните относно произведението. Ако някоя разпоредба на лиценза е невалидна или неизпълнима съгласно приложимото право, това не влияе върху валидността или приложимостта на лиценза като цяло. Такава разпоредба ще се тълкува или измени така, както е необходимо, за да стане валидна и изпълнима. Европейската комисия може да публикува други езикови версии или нови версии на настоящия лиценз или актуализирани версии на допълнението, доколкото това е необходимо или уместно, без да ограничава обхвата на правата, предоставени от лиценза. Новите версии на този лиценз ще се публикуват с уникален номер на версията. Всички езикови версии на настоящия лиценз, одобрени от Европейската комисия, са еднакво валидни. Страните по лиценза могат да използват предпочитаната от тях езикова версия. + +14.Компетентен съд +Без да се засяга конкретно споразумение между страните, +— всеки спор, произтичащ от тълкуването на настоящия лиценз, възникнал между институциите, органите, службите или агенциите на Европейския съюз в качеството им на лицензодател, и всеки лицензополучател, подлежи на юрисдикцията на Съда на Европейския съюз, както е посочено в член 272 от Договора за функционирането на Европейския съюз, +— всеки спор, възникнал между други страни и произтичащ от тълкуването на настоящия лиценз, подлежи на изключителната юрисдикция на компетентния съд, където лицензодателят пребивава или упражнява основната си дейност. + +15.Приложимо законодателство +Без да се засяга конкретно споразумение между страните, +— настоящият лиценз се управлява от правото на държавата — членка на Европейския съюз, в която лицензодателят е установил седалище, пребивава или има регистриран адрес на управление, — ако лицензодателят не е установил седалище, не пребивава или няма регистриран адрес на управление в държава — членка на Европейския съюз, настоящият лиценз се управлява от белгийското право. + +Допълнение +„Съвместими лицензи“ съгласно член 5 от EUPL са: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) за произведения, различни от софтуер +— European Union Public Licence (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence +— Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+) +Европейската комисия може да актуализира настоящото допълнение с по-нови версии на горепосочените лицензи, без да издава нова версия на EUPL, доколкото те гарантират правата, предоставени с член 2 от настоящия лиценз и защитават от придобиването на изключителни права върху изходния код, обхванат от него. +За всички други изменения или добавяния към настоящото допълнение се изисква изготвянето на нова версия на EUPL. diff --git a/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 CS.txt b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 CS.txt new file mode 100644 index 0000000..2f9cd63 --- /dev/null +++ b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 CS.txt @@ -0,0 +1,103 @@ +VEŘEJNÁ LICENCE EVROPSKÉ UNIE v. 1.2 +EUPL © Evropská unie 2007, 2016 +Tato veřejná licence Evropské unie („EUPL“) se vztahuje na dílo (ve smyslu níže uvedených definic), které se poskytuje podle podmínek této licence. Použití díla v rozporu s touto licencí je zakázáno (v míře, v jaké se na uvedené použití vztahuje právo držitele autorských práv k dílu). +Dílo se poskytuje podle podmínek této licence, pokud poskytovatel licence (ve smyslu níže uvedených definic) bezprostředně za doložku o autorských právech k dílu umístil toto upozornění: + Na toto dílo se vztahuje licence EUPL +nebo jakýmkoli jiným způsobem vyjádřil úmysl, aby se dílo poskytovalo podle licence EUPL. + +1.Definice +V rámci této licence mají následující výrazy tento význam: +— „Licencí“ se rozumí tato licence. +— „Původním dílem“ se rozumí dílo nebo software šířené nebo sdělené poskytovatelem licence podle této licence, dostupné jako zdrojový kód anebo též jako spustitelný kód. +— „Odvozenými díly“ se rozumí díla nebo software, které by nabyvatel licence mohl vytvořit na základě původního díla nebo jeho úprav. V této licenci není definováno, jaká musí být míra úprav nebo závislosti na původním díle, aby bylo považováno za odvozené dílo; tuto míru určuje autorské právo použitelné v zemi podle článku 15. +— „Dílem“ se rozumí původní dílo nebo díla z něj odvozená. +— „Zdrojovým kódem“ se rozumí podoba díla čitelná pro člověka, kterou mohou lidé nejpohodlněji analyzovat a upravovat. +— „Spustitelným kódem“ se rozumí takový kód, který byl obecně sestaven a jenž má být interpretován počítačem jako program. +— „Poskytovatelem licence“ se rozumí fyzická nebo právnická osoba, která dílo podle licence šíří nebo sděluje. +— „Přispěvatelem“ se rozumí fyzická nebo právnická osoba, jež dílo podle licence upraví nebo jinak přispěje k vytvoření odvozeného díla. +— „Nabyvatelem licence“ nebo „Vámi“ se rozumí fyzická nebo právnická osoba, která používá dílo podle podmínek licence. +— „Šířením“ nebo „sdělováním“ se rozumí prodej, předání, zapůjčení, pronájem, šíření, sdělování, přenos nebo jiný způsob zpřístupnění kopií díla nebo zpřístupnění jeho podstatných funkcí jakékoli fyzické nebo právnické osobě, a to online nebo offline. + +2.Rozsah práv udělených licencí +Poskytovatel licence Vám tímto po dobu trvání autorských práv k původnímu dílu udílí celosvětovou, bezúplatnou, nevýhradní licenci s možností poskytování podlicence, k těmto činnostem: +— používání díla za jakýchkoli okolností a pro veškerá použití, +— rozmnožování díla, +— úpravě díla a vytvoření odvozených děl na základě díla, +— sdělování veřejnosti, včetně práva zpřístupnit nebo zobrazit dílo nebo jeho kopie veřejnosti, popřípadě veřejně dílo provozovat, +— šíření díla nebo jeho kopií, +— zapůjčení a pronájmu díla nebo jeho kopií, +— poskytování podlicencí k dílu nebo jeho kopiím. +Uvedená práva lze uplatnit na všechna média, nosiče a formáty, které jsou v současnosti známé nebo budou v budoucnu vynalezeny, do té míry, do jaké to připouští rozhodné právo. +V zemích, kde se uplatňují osobnostní práva, se poskytovatel licence vzdává práva vykonávat své osobnostní právo v rozsahu, v jakém to rozhodné právo umožňuje, aby tak byl umožněn účinný výkon majetkových práv výše uvedených. +Poskytovatel licence v míře nezbytné k využívání práv udělených k dílu podle této licence udílí nabyvateli licence bezúplatná, nevýlučná práva na využití případných patentů náležejících poskytovateli licence. + +3.Sdělování zdrojového kódu +Poskytovatel licence může poskytnout dílo buď v podobě zdrojového kódu, nebo jako spustitelný kód. Pokud se dílo poskytuje v podobě spustitelného kódu, poskytovatel licence navíc společně s každou kopií díla, kterou šíří nebo na ni odkazuje, poskytne strojově čitelné vyhotovení zdrojového kódu díla; může též v závěru doložky o autorských plánech odkázat na umístění, kde se po dobu, kdy poskytovatel licence šíří nebo sděluje dílo, nachází snadno a volně dostupný zdrojový kód. + +4.Omezení autorských práv +Žádným ustanovením této licence nemůže být nabyvatel licence zbaven výhod z případných výjimek z výlučných práv majitelů práv k dílu nebo případného omezení těchto výlučných práv, nebo z vyčerpání uvedených práv nebo z jiných relevantních omezení vztahujících se k takovým právům. + +5.Závazky nabyvatele licence +Udělení uvedených práv podléhá určitým omezením a závazkům vůči nabyvateli licence. Jedná se o tyto závazky: + +Právo na označení: Nabyvatel licence zachová beze změny veškerá oznámení týkající se autorských práv, patentů či ochranných známek a veškerá oznámení odkazující na licenci a na vyloučení záruk. Kopii takových oznámení a kopii licence musí nabyvatel licence připojit ke každé kopii díla, kterou šíří nebo sděluje. Nabyvatel licence musí zajistit, aby odvozené dílo bylo opatřeno výrazným oznámením, že původní dílo bylo upraveno, a též datem úpravy. + +Ustanovení o nezměnitelnosti podmínek (tzv. copyleft clause): Pokud nabyvatel licence šíří nebo sděluje kopie původních děl nebo odvozených děl, uvedené šíření nebo sdělování bude probíhat podle podmínek této licence nebo podle pozdější verze této licence, není-li původní dílo výslovně šířeno pouze pod touto verzí licence – např. označením „výlučně EUPL v. 1.2“. Nabyvatel licence (který se stává poskytovatelem licence) nemůže v souvislosti s dílem nebo odvozeným dílem nabízet nebo ukládat žádné dodatečné podmínky, které by měnily nebo omezovaly podmínky licence. + +Ustanovení o slučitelnosti: Pokud nabyvatel licence šíří nebo sděluje odvozená díla nebo jejich kopie na základě jak díla, tak jiného díla, na které se vztahuje slučitelná licence, lze tak činit podle podmínek uvedené slučitelné licence. Pro účely tohoto ustanovení se „slučitelnou licencí“ rozumí licence uvedené v dodatku této licence. Jsou-li závazky nabyvatele licence podle slučitelné licence v rozporu s jeho závazky podle této licence, mají přednost závazky dle slučitelné licence. + +Poskytování zdrojového kódu: Při šíření nebo sdělování kopií díla nabyvatel licence poskytne strojově čitelné znění zdrojového kódu nebo odkáže na umístění, kde po dobu, kdy nabyvatel licence pokračuje v šíření nebo sdělování díla, je uvedený zdrojový kód snadno a volně přístupný. + +Právní ochrana: Touto licencí se nepovoluje použít obchodní názvy, ochranné známky pro výrobky a služby nebo názvy poskytovatele licence, s výjimkou případů, kdy tento požadavek vzniká s ohledem na přiměřené a obvyklé použití při popisu původu díla a při reprodukci obsahu doložky o autorských právech. + +6.Řetězec autorství +Původní poskytovatel licence prohlašuje, že je majitelem autorských práv k původnímu dílu, jež jsou předmětem této licence, nebo že mu k nim byla udělena licence a že má pravomoc a oprávnění licenci udělit. +Každý přispěvatel prohlašuje, že je majitelem autorských práv k úpravám, kterými dílo mění, nebo že mu k nim byla udělena licence a že má pravomoc a oprávnění licenci udělit. +Kdykoli přijmete licenci, původní poskytovatel licence a následní přispěvatelé Vám udílejí licenci ke svým příspěvkům k dílu podle podmínek této licence. + +7.Vyloučení záruky +Dílo se chápe jako dílo, které se stále vyvíjí a které četní přispěvatelé průběžně zdokonalují. Nejedná se o hotové dílo, a může proto obsahovat vady či chyby v programu, které se při takovémto způsobu vývoje běžně vyskytují. Z uvedeného důvodu se dílo podle licence poskytuje v podobě tak, jak je, a bez jakýchkoli záruk k dílu, včetně, mimo jiné, obchodovatelnosti, vhodnosti pro konkrétní účel, bezchybnosti a nechybovosti, přesnosti, neporušení práv duševního vlastnictví vyjma práva autorského, jak je uvedeno v článku 6 této licence. Toto odmítnutí záruky je nedílnou součástí licence a podmínkou pro udělení jakýchkoli práv k dílu. + +8.Vyloučení odpovědnosti +S výjimkou případů úmyslného pochybení nebo škod přímo způsobených fyzickým osobám nenese poskytovatel licence v žádném případě odpovědnost za jakékoli přímé nebo nepřímé škody, hmotnou nebo mravní újmu či jakékoli jiné škody vyplývající z licence nebo použití díla, včetně škod způsobených ztrátou dobré pověsti, přerušením práce, poruchou nebo nesprávným fungováním počítače, ztrátou dat nebo jakýchkoli škod komerční povahy, a to i tehdy, pokud poskytovatel licence byl na možnost takové škody upozorněn. Poskytovatel licence však ponese odpovědnost podle zákonů týkajících se odpovědnosti za škodu způsobenou vadou výrobku v míře, v jaké se takové zákony na dané dílo vztahují. + +9.Dodatečné dohody +Při rozšiřování díla se můžete rozhodnout uzavřít dodatečné dohody, v nichž se vymezí povinnosti nebo služby v souladu s touto licencí. Pokud však na sebe vezmete závazky, můžete jednat pouze vlastním jménem a výhradně na vlastní odpovědnost, nikoli jménem původního poskytovatele licence či jakéhokoli dalšího přispěvatele, a pouze pokud souhlasíte s tím, že každého přispěvatele odškodníte, budete hájit a uchráníte před škodou nebo uplatňovanými nároky, pokud jde o jakoukoli odpovědnost vzniklou uvedenému přispěvateli v důsledku skutečnosti, že jste přijali záruku nebo dodatečnou odpovědnost. + +10.Přijetí licence +S ustanoveními této licence lze vyjádřit souhlas kliknutím na ikonu „Souhlasím“ („I agree“) umístěnou pod oknem, kde je zobrazeno znění této licence, nebo vyjádřením souhlasu obdobným způsobem podle rozhodného práva. Kliknutím na uvedenou ikonu vyjadřujete zřejmý a neodvolatelný souhlas s touto licencí a veškerými jejími podmínkami. +Obdobně tuto licenci a veškeré její podmínky neodvolatelně přijímáte, pokud vykonáváte práva, která jsou Vám poskytnuta v souladu s článkem 2 této licence, např. pokud dílo užíváte, vytváříte odvozené dílo nebo dílo nebo jeho kopie šíříte nebo sdělujete. + +11.Informování veřejnosti +Pokud dílo šíříte nebo sdělujete prostřednictvím elektronické komunikace (např. nabízíte stažení díla ze vzdáleného umístění), musí příslušný distribuční kanál nebo média (např. internetové stránky) uvádět alespoň takové informace určené veřejnosti, které jsou požadovány rozhodným právem ohledně poskytovatele licence, licence samotné a způsobu jejího zpřístupnění, uzavření, uchovávání a reprodukování nabyvatelem licence. + +12.Zánik licence +Platnost licence a práv touto licencí udělených bez dalšího zaniká, pokud nabyvatel licence poruší jakýmkoli způsobem podmínky licence. Uvedeným zánikem není ukončena licence jakékoli osoby, která podle licence dílo obdržela od nabyvatele licence, za podmínky, že takové osoby nadále plně jednají v souladu s podmínkami licence. + +13.Různé +Aniž je dotčen výše uvedený článek 9, představuje licence úplnou dohodu mezi stranami, pokud jde o dílo. Je-li podle rozhodného práva jakékoli ustanovení této licence neplatné nebo nevymahatelné, neovlivní tato skutečnost platnost nebo vymahatelnost licence jako celku. Takové ustanovení se vyloží nebo podle potřeby upraví tak, aby bylo platné a vymahatelné. Evropská komise může v požadované a přiměřené míře zveřejnit další jazykové verze nebo nové verze této licence nebo aktualizované verze dodatku, aniž by omezila rozsah práv udělených licencí. Novým verzím bude při zveřejnění přiděleno jedinečné číslo verze. Všechny jazykové verze této licence schválené Evropskou komisí mají stejnou platnost. Strany mohou využít jazykové verze dle svého výběru. + +14.Soudní příslušnost +Aniž jsou dotčeny zvláštní dohody mezi stranami, +— soudní spor, který by popřípadě vyplynul z výkladu této licence mezi orgány, úřady nebo agenturami Evropské unie jakožto poskytovateli licence a jakýmkoli nabyvatelem licence, se bude řídit pravomocí Soudního dvora Evropské unie, jak stanoví článek 272 Smlouvy o fungování Evropské unie, +— soudní spor, který by popřípadě vyplynul z výkladu této licence mezi jinými stranami, se bude řídit výlučnou pravomocí příslušného soudu, kde má poskytovatel licence bydliště nebo vykonává hlavní obchodní činnost. + +15.Rozhodné právo +Aniž jsou dotčeny zvláštní dohody mezi stranami, +— tato licence se řídí právem toho členského státu Evropské unie, kde má poskytovatel licence své sídlo, bydliště nebo sídlo podnikání, +— pokud poskytovatel licence nemá sídlo, bydliště nebo sídlo podnikání v některém členském státě Evropské unie, řídí se tato licence belgickým právem. + +Dodatek +„Slučitelnými licencemi“ podle článku 5 licence EUPL se rozumí: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) pro díla jiná než software +— veřejná licence Evropské unie (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence – Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+) +Evropská komise může tento dodatek aktualizovat, aby zahrnoval pozdější verze uvedených licencí, bez zavedení nové verze EUPL, pokud uvedené licence zajišťují práva udělená článkem 2 této licence a chrání zdrojový kód, který je jejím předmětem, před výhradním přivlastněním. +Všechny ostatní změny nebo doplnění k tomuto dodatku vyžadují novou verzi EUPL. \ No newline at end of file diff --git a/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 DA.txt b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 DA.txt new file mode 100644 index 0000000..452260a --- /dev/null +++ b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 DA.txt @@ -0,0 +1,99 @@ +DEN EUROPÆISKE UNIONS OFFENTLIGE LICENS v. 1.2 EUPL +© Den Europæiske Union 2007, 2016 +Den Europæiske Unions Offentlige Licens (»EUPL«) gælder for det værk (som defineret nedenfor), der stilles til rådighed i henhold til vilkårene i denne licens. Enhver anden brug af værket end den, der gives tilladelse til i denne licens, er forbudt (for så vidt som denne brug er omfattet af de rettigheder, der tilkommer indehaveren af ophavsretten til værket). +Værket stilles til rådighed på vilkårene i denne licens, når licensgiveren (som defineret nedenfor) har gjort følgende anmærkning umiddelbart efter ophavsretsnotitsen om værket: + Licenseret i henhold til EUPL +eller på anden måde har udtrykt sin indforståelse med at licensere værket i henhold til EUPL. + +1.Definitioner +I denne licens forstås ved: +— »licensen«:denne licens +— »det oprindelige værk«:det værk eller den software, der spredes eller formidles af licensgiveren i henhold til denne licens, og som stilles til rådighed som kildekode og efter omstændighederne også som eksekverbar kode +— »bearbejdede værker«:værker eller software, der kan frembringes af licenstageren på grundlag af det oprindelige værk eller ændringer heraf. I denne licens fastlægges ikke, hvor høj en grad af ændring eller afhængighed af det oprindelige værk, der kræves, for at et værk kan betragtes som et bearbejdet værk; dette bestemmes af de ophavsretlige regler i det land, der henvises til i artikel 15 +— »værket«:det oprindelige værk eller bearbejdede værker på grundlag heraf +— »kildekoden«:den for mennesker læselige form af værket, som det er nemmest at studere og foretage ændringer i +— »eksekverbar kode«:enhver kode, der i almindelighed er kompileret, og som er beregnet til at blive fortolket af en computer som et program +— »licensgiver«:den fysiske eller juridiske person, der spreder eller formidler værket i henhold til licensen +— »bidragyder«:enhver fysisk eller juridisk person, der ændrer værket i henhold til licensen, eller som på anden vis bidrager til frembringelsen af et bearbejdet værk +— »licenstager« eller »De«:enhver fysisk eller juridisk person, der gør brug af softwaren i henhold til licensens vilkår +— »spredning« eller »formidling«:enhver handling, der består i at sælge, give, udlåne, udleje, sprede, formidle eller transmittere eksemplarer af værket eller på anden måde gøre dem tilgængelige, enten online eller offline, eller give adgang til værkets væsentlige funktioner for en anden fysisk eller juridisk person. + +2.Omfanget af licensrettighederne +Licensgiveren meddeler Dem herved en verdensomspændende, vederlagsfri, ikke-eksklusiv licens til at meddele underlicenser og til at gøre følgende, så længe ophavsretten til det oprindelige værk består: +— anvende værket under enhver omstændighed og til en hvilken som helst brug — fremstille eksemplarer af værket +— ændre i det oprindelige værk og frembringe bearbejdede værker på grundlag af værket +— overføre værket til almenheden, herunder retten til at gøre værket eller eksemplarer heraf tilgængeligt for almenheden, at fremvise værket eller eksemplarer heraf offentligt samt efter omstændighederne at fremføre værket offentligt +— sprede værket eller eksemplarer heraf +— udlåne og udleje værket eller eksemplarer heraf +— meddele underlicenser til værket eller eksemplarer heraf. +Disse rettigheder kan udøves ved brug af alle nu kendte og senere udviklede medier, kanaler og formater, for så vidt det er tilladt i henhold til gældende ret. I lande, hvor ideelle rettigheder er beskyttede, giver licensgiveren afkald på sin ret til at udøve sine ideelle rettigheder i det omfang, det er tilladt i henhold til loven, for at den licensering af de økonomiske rettigheder, der er meddelt ovenfor, kan få virkning. Licensgiveren meddeler licenstageren vederlagsfri, ikke-eksklusive rettigheder til brug af alle sine patenter i det omfang, det er nødvendigt for at udøve de rettigheder til værket, der meddeles i henhold til denne licens. + +3.Formidling af kildekoden +Licensgiveren kan stille værket til rådighed enten i form af kildekode eller som eksekverbar kode. Hvis værket stilles til rådighed som eksekverbar kode, udleverer licensgiveren desuden et maskinlæsbart eksemplar af kildekoden til værket sammen med hvert eksemplar af værket, som licensgiveren distribuerer, eller henviser i en anmærkning efter den ophavsretsnotits, der er påført værket, til et arkiv, hvor kildekoden er let og frit tilgængelig, så længe licensgiveren spreder og/eller formidler værket. + +4.Indskrænkninger i ophavsretten +Intet i denne licens skal anses for at afskære licenstageren fra at påberåbe sig en undtagelse fra eller indskrænkning i rettighedshaverens eksklusive rettigheder til værket, eller fra at påberåbe sig konsumption af disse rettigheder eller andre gældende indskrænkninger heri. + +5.Licenstagerens forpligtelser +Indrømmelsen af de ovennævnte rettigheder er undergivet visse begrænsninger og forpligtelser, der gælder for licenstageren. Forpligtelserne er følgende: + +Ret til navngivning: Licenstageren skal bibeholde alle notitser vedrørende ophavsret, patenter og varemærker samt alle meddelelser, hvori der henvises til licensen og til ansvarsfraskrivelsen. Licenstageren skal vedlægge hvert eksemplar af værket, som spredes eller formidles, et eksemplar af disse notitser og af licensen. Licenstageren skal sikre, at ethvert bearbejdet værk forsynes med en tydelig meddelelse om, at værket er blevet ændret samt datoen for ændringen. + +Copyleft-klausul: Hvis licenstageren spreder eller formidler eksemplarer af de oprindelige værker eller bearbejdede værker, skal det ske på de vilkår, der er fastsat i denne licens eller i en senere version af denne licens, medmindre det udtrykkeligt er fastsat, at det oprindelige værk alene spredes på de vilkår, der er fastsat i denne version af licensen — f. eks. ved at angive »kun EUPL v. 1.2«. Licenstageren (der bliver licensgiver) kan ikke tilbyde eller knytte yderligere vilkår eller betingelser, der ændrer eller begrænser vilkårene i licensen, til værket eller det bearbejdede værk. + +Kompatibilitetsklausul: Hvis licenstageren spreder eller formidler et bearbejdet værk eller eksemplarer heraf, der er baseret både på dette værk og på et andet værk, der er omfattet af en kompatibel licens, kan denne spredning eller formidling ske på de vilkår, der er fastsat i den kompatible licens. I nærværende klausul forstås ved »kompatibel licens« de licenser, der er anført i tillægget til denne licens. Hvis licenstagerens forpligtelser i henhold til den kompatible licens er i strid med vedkommendes forpligtelser i henhold til denne licens, gælder forpligtelserne i den kompatible licens. + +Tilrådighedsstillelse af kildekoden: Når licenstageren spreder eller formidler eksemplarer af værket, skal de ledsages af et maskinlæsbart eksemplar af kildekoden eller en henvisning til et arkiv, hvor kildekoden er let og gratis tilgængelig, så længe licenstageren spreder eller formidler værket. + +Retsbeskyttelse: Denne licens giver ikke licenstageren ret til at anvende licensgiverens firmanavn, varemærker, mærker for tjenesteydelser eller andre navne, ud over hvor det er nødvendigt for på rimelig og sædvanlig vis at gøre rede for værkets oprindelse og gengive indholdet af ophavsretsnotitsen. + +6.Licensgiverkæde +Den oprindelige licensgiver indestår for, at han er indehaver af ophavsretten til det oprindelige værk, der meddeles licens til, eller at han har fået overdraget ophavsretten i henhold til en licens, og at han har beføjelser og myndighed til at meddele licensen. +Hver bidragyder indestår for, at han er indehaver af ophavsretten til de ændringer, som vedkommende har foretaget i værket, eller at han har fået overdraget ophavsretten i henhold til en licens, og at han har beføjelser og myndighed til at meddele licensen. +Hver gang De accepterer licensen, meddeler den oprindelige licensgiver og de efterfølgende bidragydere Dem en licens til deres bidrag til værket på vilkårene i denne licens. + +7.Fraskrivelse af ansvar for værket +Værket udvikles løbende og forbedres hele tiden af forskellige bidragydere. Det er ikke et færdigt arbejde og kan derfor indeholde fejl eller »bugs«, hvilket er typisk ved denne type udvikling. Af denne grund stilles værket til rådighed i henhold til denne licens »som det er og forefindes« og uden indeståelse af nogen art for værket, herunder, men ikke begrænset til, garanti vedrørende salgbarhed, anvendelighed til et bestemt formål, fravær af fejl og mangler, nøjagtighed og overholdelse af immaterialrettigheder bortset fra den ophavsret, der er omhandlet i artikel 6 i denne licens. Denne ansvarsfraskrivelse er en væsentlig del af denne licens og en betingelse for at meddele rettigheder til værket. + +8.Fraskrivelse af erstatningsansvar +Bortset fra tilfælde af forsætlig skadevoldende adfærd og direkte personskade er licensgiveren under ingen omstændigheder erstatningsansvarlig for nogen form for direkte eller indirekte økonomisk eller ikke-økonomisk skade, der forvoldes på grund af licensen eller brugen af værket, herunder, men ikke begrænset til, tab af goodwill, tab som følge af arbejdsafbrydelse, computersvigt eller -fejl, tab af data og andet erhvervsmæssigt tab, heller ikke hvis licensgiveren er blevet gjort opmærksom på muligheden af sådanne skader. Licensgiveren er dog ansvarlig i henhold til lovgivningen om produktansvar, for så vidt som denne finder anvendelse på værket. + +9.Tillægsaftaler +Hvis De distribuerer værket, kan De vælge at indgå en tillægsaftale, hvori forpligtelser eller tjenesteydelser, der er forenelige med denne licens, fastsættes. Hvis De påtager Dem forpligtelser, handler De imidlertid udelukkende på egne vegne og på eget ansvar, og ikke på vegne af den oprindelige licensgiver eller andre bidragydere, og kun hvis De påtager Dem at forsvare og holde hver enkelt bidragyder skadesløs for eventuelle erstatningskrav eller andre krav, der rejses mod bidragyderen som følge af, at De har påtaget Dem garantiforpligtelser eller yderligere erstatningsansvar. + +10.Accept af licensen +De kan acceptere bestemmelserne i denne licens ved at klikke på ikonet »Acceptér«, der vises under vinduet med licensteksten, eller ved at tilkendegive Deres samtykke på en tilsvarende måde i overensstemmelse med gældende ret. Ved at klikke på det nævnte ikon tilkendegiver De Deres utvetydige og uigenkaldelige accept af denne licens og alle dens vilkår og betingelser. Ligeledes accepterer De uigenkaldeligt denne licens og alle dens vilkår og betingelser ved at udøve enhver af Deres rettigheder i henhold til licensens artikel 2, herunder retten til at bruge værket, frembringe bearbejdede værker og sprede eller formidle værket eller eksemplarer heraf. + +11.Oplysninger til offentligheden +Hvis De spreder eller formidler værket via en elektronisk kommunikationskanal, (f.eks. ved at give mulighed for at downloade værket fra en fjernlokation), skal distributionskanalen eller -mediet (f.eks. en hjemmeside) som minimum forsyne offentligheden med de oplysninger, der kræves efter gældende ret, om licensgiveren, licensen, og hvordan licenstageren kan få adgang til licensen og acceptere, opbevare og gengive den. + +12.Licensens ophør +Licensen og rettighederne i henhold til den ophører automatisk ved licenstagerens misligholdelse af licensvilkårene. Dette ophør medfører ikke, at de personer, som har modtaget værket fra licenstageren i henhold til den pågældende licens, mister deres egen licens, medmindre disse personer ikke længere fuldt ud overholder licensvilkårene. + +13.Andre forhold +Med forbehold af artikel 9 ovenfor udgør licensen den fuldstændige aftale mellem parterne om værket. Hvis en bestemmelse i licensen er ugyldig eller ikke kan håndhæves i henhold til gældende ret, berører dette ikke gyldigheden af licensen som helhed eller muligheden for at håndhæve denne. En sådan bestemmelse skal så vidt muligt fortolkes eller tilpasses således, at den bliver gyldig og kan håndhæves. Europa-Kommissionen kan offentliggøre andre sprogudgaver eller nye versioner af denne licens eller ajourførte versioner af tillægget, for så vidt som det er nødvendigt og rimeligt, uden at det indskrænker omfanget af licensrettighederne. Nye versioner af licensen vil blive offentliggjort med et entydigt versionsnummer. Alle de af Europa-Kommissionen godkendte sprogudgaver af denne licens har identisk værdi. Parterne kan frit vælge mellem de forskellige sprogudgaver. + +14.Kompetence +Uden at det berører specifikke aftale mellem parterne +— henhører enhver retstvist, der måtte opstå ved fortolkningen af denne licens, mellem Den Europæiske Unions institutioner, organer, kontorer eller agenturer i dennes egenskab af licensgiver og enhver licenstager under Den Europæiske Unions Domstols kompetence, jf. artikel 272 i traktaten om Den Europæiske Unions funktionsmåde +— i retstvister mellem andre parter vedrørende fortolkningen af denne licens har retten på det sted, hvor licensgiveren har bopæl, eller hvor licensgiverens hovedforretningssted er beliggende, enekompetence. + +15.Gældende lovgivning +Uden at det berører specifikke aftale mellem parterne +— finder lovgivningen i den EU-medlemsstat, hvor licensgiveren har hovedsæde, bopæl eller hjemsted, anvendelse på denne licens +— denne licens er underlagt belgisk lovgivning, hvis licensgiveren ikke har hovedsæde, bopæl eller hjemsted i en EU- medlemsstat. + +Tillæg +»Kompatible licenser« ifølge artikel 5 i EUPL er: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for andre værker end software +— Den Europæiske Unions Offentlige Licens (EUPL) v. 1.1, v. 1,2 +— Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) eller Strong Reciprocity (LiLiQ-R+) +Europa-Kommissionen vil eventuelt ajourføre dette tillæg med senere versioner af ovennævnte licenser uden at udarbejde en ny version af Den Europæiske Unions Offentlige Licens, så længe disse versioner af licensen sikrer de rettigheder, der gives i artikel 2 i nærværende licens, og beskytter den omfattede kildekode fra monopol. +Alle andre ændringer eller tilføjelser til dette tillæg kræver forelæggelse af en ny version af Den Europæiske Unions Offentlige Licens. \ No newline at end of file diff --git a/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 DE.txt b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 DE.txt new file mode 100644 index 0000000..d7865ce --- /dev/null +++ b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 DE.txt @@ -0,0 +1,101 @@ +OPEN-SOURCE-LIZENZ FÜR DIE EUROPÄISCHE UNION v. 1.2 +EUPL © Europäische Union 2007, 2016 +Diese Open-Source-Lizenz für die Europäische Union („EUPL“) gilt für Werke (im Sinne der nachfolgenden Begriffsbestimmung), die unter EUPL-Bedingungen zur Verfügung gestellt werden. Das Werk darf nur in der durch diese Lizenz gestatteten Form genutzt werden (insoweit eine solche Nutzung dem Urheber vorbehalten ist). +Das Werk wird unter den Bedingungen dieser Lizenz zur Verfügung gestellt, wenn der Lizenzgeber (im Sinne der nachfolgenden Begriffsbestimmung) den folgenden Hinweis unmittelbar hinter dem Urheberrechtshinweis dieses Werks anbringt: + Lizenziert unter der EUPL +oder in einer anderen Form zum Ausdruck bringt, dass er es unter der EUPL lizenzieren möchte. + +1.Begriffsbestimmungen +Für diese Lizenz gelten folgende Begriffsbestimmungen: +— „Lizenz“:diese Lizenz. +— „Originalwerk“:das Werk oder die Software, die vom Lizenzgeber unter dieser Lizenz verbreitet oder zugänglich gemacht wird, und zwar als Quellcode und gegebenenfalls auch als ausführbarer Code. +— „Bearbeitungen“:die Werke oder Software, die der Lizenznehmer auf der Grundlage des Originalwerks oder seiner Bearbeitungen schaffen kann. In dieser Lizenz wird nicht festgelegt, wie umfangreich die Änderung oder wie stark die Abhängigkeit vom Originalwerk für eine Einstufung als Bearbeitung sein muss; dies bestimmt sich nach dem Urheberrecht, das in dem unter Artikel 15 aufgeführten Land anwendbar ist. +— „Werk“:das Originalwerk oder seine Bearbeitungen. +— „Quellcode“:diejenige Form des Werkes, die zur Auffassung durch den Menschen bestimmt ist und die am besten geeignet ist, um vom Menschen verstanden und verändert zu werden. +— „Ausführbarer Code“:die — üblicherweise — kompilierte Form des Werks, die von einem Computer als Programm ausgeführt werden soll. +— „Lizenzgeber“:die natürliche oder juristische Person, die das Werk unter der Lizenz verbreitet oder zugänglich macht. +— „Bearbeiter“:jede natürliche oder juristische Person, die das Werk unter der Lizenz verändert oder auf andere Weise zur Schaffung einer Bearbeitung beiträgt. +— „Lizenznehmer“ („Sie“):jede natürliche oder juristische Person, die das Werk unter den Lizenzbedingungen nutzt. +— „Verbreitung“ oder „Zugänglichmachung“:alle Formen von Verkauf, Überlassung, Verleih, Vermietung, Verbreitung, Weitergabe, Übermittlung oder anderweitiger Online- oder Offline-Bereitstellung von Vervielfältigungen des Werks oder Zugänglichmachung seiner wesentlichen Funktionen für dritte natürliche oder juristische Personen. + +2.Umfang der Lizenzrechte +Der Lizenzgeber erteilt Ihnen hiermit für die Gültigkeitsdauer der am Originalwerk bestehenden Urheberrechte eine weltweite, unentgeltliche, nicht ausschließliche, unterlizenzierbare Lizenz, die Sie berechtigt: +— das Werk uneingeschränkt zu nutzen, +— das Werk zu vervielfältigen, +— das Werk zu verändern und Bearbeitungen auf der Grundlage des Werks zu schaffen, +— das Werk öffentlich zugänglich zu machen, was das Recht einschließt, das Werk oder Vervielfältigungsstücke davon öffentlich bereitzustellen oder wahrnehmbar zu machen oder das Werk, soweit möglich, öffentlich aufzuführen, +— das Werk oder Vervielfältigungen davon zu verbreiten, +— das Werk oder Vervielfältigungen davon zu vermieten oder zu verleihen, +— das Werk oder Vervielfältigungen davon weiter zu lizenzieren. +Für die Wahrnehmung dieser Rechte können beliebige, derzeit bekannte oder künftige Medien, Träger und Formate verwendet werden, soweit das geltende Recht dem nicht entgegensteht. Für die Länder, in denen Urheberpersönlichkeitsrechte an dem Werk bestehen, verzichtet der Lizenzgeber im gesetzlich zulässigen Umfang auf seine Urheberpersönlichkeitsrechte, um die Lizenzierung der oben aufgeführten Verwertungsrechte wirksam durchführen zu können. Der Lizenzgeber erteilt dem Lizenznehmer ein nicht ausschließliches, unentgeltliches Nutzungsrecht an seinen Patenten, sofern dies zur Ausübung der durch die Lizenz erteilten Nutzungsrechte am Werk notwendig ist. + +3.Zugänglichmachung des Quellcodes +Der Lizenzgeber kann das Werk entweder als Quellcode oder als ausführbaren Code zur Verfügung stellen. Stellt er es als ausführbaren Code zur Verfügung, so stellt er darüber hinaus eine maschinenlesbare Kopie des Quellcodes für jedes von ihm verbreitete Vervielfältigungsstück des Werks zur Verfügung, oder er verweist in einem Vermerk im Anschluss an den dem Werk beigefügten Urheberrechtshinweis auf einen Speicherort, an dem problemlos und unentgeltlich auf den Quellcode zugegriffen werden kann, solange der Lizenzgeber das Werk verbreitet oder zugänglich macht. + +4.Einschränkungen des Urheberrechts +Es ist nicht Zweck dieser Lizenz, Ausnahmen oder Schranken der ausschließlichen Rechte des Urhebers am Werk, die dem Lizenznehmer zugutekommen, einzuschränken. Auch die Erschöpfung dieser Rechte bleibt von dieser Lizenz unberührt. + +5.Pflichten des Lizenznehmers +Die Einräumung der oben genannten Rechte ist an mehrere Beschränkungen und Pflichten für den Lizenznehmer gebunden: + +Urheberrechtshinweis, Lizenztext, Nennung des Bearbeiters: Der Lizenznehmer muss alle Urheberrechts-, Patent- oder Markenrechtshinweise und alle Hinweise auf die Lizenz und den Haftungsausschluss unverändert lassen. Jedem von ihm verbreiteten oder zugänglich gemachten Vervielfältigungsstück des Werks muss der Lizenznehmer diese Hinweise sowie diese Lizenz beifügen. Der Lizenznehmer muss auf jedem abgeleiteten Werk deutlich darauf hinweisen, dass das Werk geändert wurde, und das Datum der Bearbeitung angeben. + +„Copyleft“-Klausel: Der Lizenznehmer darf Vervielfältigungen des Originalwerks oder Bearbeitungen nur unter den Bedingungen dieser EUPL oder einer neueren Version dieser Lizenz verbreiten oder zugänglich machen, außer wenn das Originalwerk ausdrücklich nur unter dieser Lizenzversion — z. B. mit der Angabe „Nur EUPL V. 1.2“ — verbreitet werden darf. Der Lizenznehmer (der zum Lizenzgeber wird) darf für das Werk oder die Bearbeitung keine zusätzlichen Bedingungen anbieten oder vorschreiben, die die Bedingungen dieser Lizenz verändern oder einschränken. + +Kompatibilitäts-Klausel: Wenn der Lizenznehmer Bearbeitungen, die auf dem Werk und einem anderen Werk, das unter einer kompatiblen Lizenz lizenziert wurde, basieren, oder die Kopien dieser Bearbeitungen verbreitet oder zugänglich macht, kann dies unter den Bedingungen dieser kompatiblen Lizenz erfolgen. Unter „kompatibler Lizenz“ ist eine im Anhang dieser Lizenz angeführte Lizenz zu verstehen. Sollten die Verpflichtungen des Lizenznehmers aus der kompatiblen Lizenz mit denjenigen aus der vorliegenden Lizenz (EUPL) in Konflikt stehen, werden die Verpflichtungen aus der kompatiblen Lizenz Vorrang haben. + +Bereitstellung des Quellcodes: Wenn der Lizenznehmer Vervielfältigungsstücke des Werks verbreitet oder zugänglich macht, muss er eine maschinenlesbare Fassung des Quellcodes mitliefern oder einen Speicherort angeben, über den problemlos und unentgeltlich so lange auf diesen Quellcode zugegriffen werden kann, wie der Lizenznehmer das Werk verbreitet oder zugänglich macht. + +Rechtsschutz: Diese Lizenz erlaubt nicht die Benutzung von Kennzeichen, Marken oder geschützten Namensrechten des Lizenzgebers, soweit dies nicht für die angemessene und übliche Beschreibung der Herkunft des Werks und der inhaltlichen Wiedergabe des Urheberrechtshinweises erforderlich ist. + +6.Urheber und Bearbeiter +Der ursprüngliche Lizenzgeber gewährleistet, dass er das Urheberrecht am Originalwerk innehat oder dieses an ihn lizenziert wurde und dass er befugt ist, diese Lizenz zu erteilen. +Jeder Bearbeiter gewährleistet, dass er das Urheberrecht an den von ihm vorgenommenen Änderungen des Werks besitzt und befugt ist, diese Lizenz zu erteilen. +Jedes Mal, wenn Sie die Lizenz annehmen, erteilen Ihnen der ursprüngliche Lizenzgeber und alle folgenden Bearbeiter eine Befugnis zur Nutzung ihrer Beiträge zum Werk unter den Bedingungen dieser Lizenz. + +7.Gewährleistungsausschluss +Die Arbeit an diesem Werk wird laufend fortgeführt; es wird durch unzählige Bearbeiter ständig verbessert. Das Werk ist nicht vollendet und kann daher Fehler („bugs“) enthalten, die dieser Art der Entwicklung inhärent sind. +Aus den genannten Gründen wird das Werk unter dieser Lizenz „so, wie es ist“ ohne jegliche Gewährleistung zur Verfügung gestellt. Dies gilt unter anderem — aber nicht ausschließlich — für Marktreife, Verwendbarkeit für einen bestimmten Zweck, Mängelfreiheit, Richtigkeit sowie Nichtverletzung von anderen Immaterialgüterrechten als dem Urheberrecht (vgl. dazu Artikel 6 dieser Lizenz). +Dieser Gewährleistungsausschluss ist wesentlicher Bestandteil der Lizenz und Bedingung für die Einräumung von Rechten an dem Werk. + +8.Haftungsausschluss/Haftungsbeschränkung +Außer in Fällen von Vorsatz oder der Verursachung von Personenschäden haftet der Lizenzgeber nicht für direkte oder indirekte, materielle oder immaterielle Schäden irgendwelcher Art, die aus der Lizenz oder der Benutzung des Werks folgen; dies gilt unter anderem, aber nicht ausschließlich, für Firmenwertverluste, Produktionsausfall, Computerausfall oder Computerfehler, Datenverlust oder wirtschaftliche Schäden, und zwar auch dann, wenn der Lizenzgeber auf die Möglichkeit solcher Schäden hingewiesen wurde. Unabhängig davon haftet der Lizenzgeber im Rahmen der gesetzlichen Produkthaftung, soweit die entsprechenden Regelungen auf das Werk anwendbar sind. + +9.Zusatzvereinbarungen +Wenn Sie das Werk verbreiten, können Sie Zusatzvereinbarungen schließen, in denen Verpflichtungen oder Dienstleistungen festgelegt werden, die mit dieser Lizenz vereinbar sind. Sie dürfen Verpflichtungen indessen nur in Ihrem eigenen Namen und auf Ihre eigene Verantwortung eingehen, nicht jedoch im Namen des ursprünglichen Lizenzgebers oder eines anderen Bearbeiters, und nur, wenn Sie sich gegenüber allen Bearbeitern verpflichten, sie zu entschädigen, zu verteidigen und von der Haftung freizustellen, falls aufgrund der von Ihnen eingegangenen Gewährleistungsverpflichtung oder Haftungsübernahme Forderungen gegen sie geltend gemacht werden oder eine Haftungsverpflichtung entsteht. + +10.Annahme der Lizenz +Sie können den Bestimmungen dieser Lizenz zustimmen, indem Sie das Symbol „Lizenz annehmen“ unter dem Fenster mit dem Lizenztext anklicken oder indem Sie Ihre Zustimmung auf vergleichbare Weise in einer nach anwendbarem Recht zulässigen Form geben. Das Anklicken des Symbols gilt als Anzeichen Ihrer eindeutigen und unwiderruflichen Annahme der Lizenz und der darin enthaltenen Klauseln und Bedingungen. In gleicher Weise gilt als Zeichen der eindeutigen und unwiderruflichen Zustimmung die Ausübung eines Rechtes, das in Artikel 2 dieser Lizenz angeführt ist, wie das Erstellen einer Bearbeitung oder die Verbreitung oder Zugänglichmachung des Werks oder dessen Vervielfältigungen. + +11.Informationspflichten +Wenn Sie das Werk verbreiten oder zugänglich machen (beispielsweise, indem Sie es zum Herunterladen von einer Website anbieten), müssen Sie über den Vertriebskanal oder das benutzte Verbreitungsmedium der Öffentlichkeit zumindest jene Informationen bereitstellen, die nach dem anwendbaren Recht bezüglich der Lizenzgeber, der Lizenz und ihrer Zugänglichkeit, des Abschlusses des Lizenzvertrags sowie darüber, wie die Lizenz durch den Lizenznehmer gespeichert und vervielfältigt werden kann, erforderlich sind. + +12.Beendigung der Lizenz +Die Lizenz und die damit eingeräumten Rechte erlöschen automatisch, wenn der Lizenznehmer gegen die Lizenzbedingungen verstößt. Ein solches Erlöschen der Lizenz führt nicht zum Erlöschen der Lizenzen von Personen, denen das Werk vom Lizenznehmer unter dieser Lizenz zur Verfügung gestellt worden ist, solange diese Personen die Lizenzbedingungen erfüllen. +13.Sonstiges +Unbeschadet des Artikels 9 stellt die Lizenz die vollständige Vereinbarung der Parteien über das Werk dar. Sind einzelne Bestimmungen der Lizenz nach geltendem Recht nichtig oder unwirksam, so berührt dies nicht die Wirksamkeit oder Durchsetzbarkeit der Lizenz an sich. Solche Bestimmungen werden vielmehr so ausgelegt oder modifiziert, dass sie wirksam und durchsetzbar sind. Die Europäische Kommission kann weitere Sprachfassungen oder neue Versionen dieser Lizenz oder aktualisierte Fassungen des Anhangs veröffentlichen, soweit dies notwendig und angemessen ist, ohne den Umfang der Lizenzrechte zu verringern. Neue Versionen werden mit einer eindeutigen Versionsnummer veröffentlicht. Alle von der Europäischen Kommission anerkannten Sprachfassungen dieser Lizenz sind gleichwertig. Die Parteien können sich auf die Sprachfassung ihrer Wahl berufen. + +14.Gerichtsstand +Unbeschadet besonderer Vereinbarungen zwischen den Parteien gilt Folgendes: +— Für alle Streitigkeiten über die Auslegung dieser Lizenz zwischen den Organen, Einrichtungen und sonstigen Stellen der Europäischen Union als Lizenzgeber und einem Lizenznehmer ist der Gerichtshof der Europäischen Union gemäß Artikel 272 des Vertrags über die Arbeitsweise der Europäischen Union zuständig; +— Gerichtsstand für Streitigkeiten zwischen anderen Parteien über die Auslegung dieser Lizenz ist allein der Ort, an dem der Lizenzgeber seinen Wohnsitz oder den wirtschaftlichen Mittelpunkt seiner Tätigkeit hat. + +15.Anwendbares Recht +Unbeschadet besonderer Vereinbarungen zwischen den Parteien gilt Folgendes: +— Diese Lizenz unterliegt dem Recht des Mitgliedstaats der Europäischen Union, in dem der Lizenzgeber seinen Sitz, Wohnsitz oder eingetragenen Sitz hat; +— diese Lizenz unterliegt dem belgischen Recht, wenn der Lizenzgeber keinen Sitz, Wohnsitz oder eingetragenen Sitz in einem Mitgliedstaat der Europäischen Union hat. + +Anlage +„Kompatible Lizenzen“ nach Artikel 5 der EUPL sind: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) für andere Werke als Software +— European Union Public Licence (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) oder Strong Reciprocity (LiLiQ-R+) +Die Europäische Kommission kann diesen Anhang aktualisieren, um neuere Fassungen der obigen Lizenzen aufzunehmen, ohne hierfür eine neue Fassung der EUPL auszuarbeiten, solange diese Lizenzen die in Artikel 2 gewährten Rechte gewährleisten und den erfassten Quellcode vor ausschließlicher Aneignung schützen. +Alle sonstigen Änderungen oder Ergänzungen dieses Anhangs bedürfen der Ausarbeitung einer neuen Version der EUPL. diff --git a/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 EL.txt b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 EL.txt new file mode 100644 index 0000000..f2860e2 --- /dev/null +++ b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 EL.txt @@ -0,0 +1,91 @@ +ΆΔΕΙΑ ΔΗΜΟΣΙΑΣ ΧΡΗΣΗΣ ΓΙΑ ΤΗΝ ΕΥΡΩΠΑΪΚΗ ΈΝΩΣΗ v. 1.2 +EUPL © Ευρωπαϊκή Ένωση 2007, 2016 +Η παρούσα άδεια δημόσιας χρήσης για την Ευρωπαϊκή Ένωση (η «EUPL») ισχύει για κάθε έργο (όπως ορίζεται παρακάτω) που καθίσταται διαθέσιμο υπό τους όρους της παρούσας άδειας. Απαγορεύεται κάθε άλλη χρήση του έργου πλην εκείνων που προβλέπονται δυνάμει της παρούσας άδειας (στον βαθμό που η εν λόγω χρήση καλύπτεται από δικαίωμα, επί του έργου, του κατόχου της πνευματικής ιδιοκτησίας). Το έργο καθίσταται διαθέσιμο βάσει των όρων της παρούσας άδειας όταν ο χορηγός της άδειας (όπως ορίζεται παρακάτω) έχει θέσει την ακόλουθη σημείωση αμέσως μετά την ανακοίνωση σχετικά με τα πνευματικά δικαιώματα για το έργο: + Αδειοδοτείται υπό τους όρους της EUPL +ή έχει εκφράσει με οποιονδήποτε άλλο τρόπο την πρόθεσή του να χορηγεί άδεια υπό τους όρους της EUPL. + +1.Ορισμοί +Στην παρούσα άδεια νοούνται ως: +— «Άδεια»:η παρούσα άδεια. +— «Πρωτότυπο έργο»:το έργο ή το λογισμικό που διανέμεται ή παρουσιάζεται στο κοινό από τον χορηγό της άδειας υπό τους όρους της παρούσας άδειας, το οποίο διατίθεται ως πηγαίος κώδικας και επίσης ως εκτελέσιμος κώδικας, κατά περίπτωση. +— «Παράγωγα έργα»:το έργο ή το λογισμικό που μπορούν να δημιουργηθούν από τον αδειούχο, με βάση το πρωτότυπο έργο ή τροποποιήσεις του. Η παρούσα άδεια δεν ορίζει ποιος είναι ο απαιτούμενος βαθμός της τροποποίησης ή της εξάρτησης από το πρωτότυπο έργο, ώστε ένα έργο να χαρακτηρίζεται παράγωγο. Το ζήτημα αυτό ρυθμίζεται από το δίκαιο περί πνευματικής ιδιοκτησίας που είναι εφαρμοστέο στη χώρα η οποία ορίζεται στο σημείο 15. +— «Έργο»:το πρωτότυπο έργο ή τα παράγωγά του έργα. +— «Πηγαίος κώδικας»:η αναγνώσιμη από τον άνθρωπο μορφή του έργου η οποία προσφέρεται καλύτερα για μελέτη και τροποποίηση. +— «Εκτελέσιμος κώδικας»:κάθε κώδικας ο οποίος συνήθως έχει μεταγλωττιστεί και προορίζεται να ερμηνευθεί ως πρόγραμμα από έναν ηλεκτρονικό υπολογιστή. +— «Χορηγός της άδειας»:το φυσικό ή νομικό πρόσωπο που διανέμει ή παρουσιάζει στο κοινό το έργο υπό τους όρους της άδειας. +— «Συντελεστής/-ές»:κάθε φυσικό ή νομικό πρόσωπο που τροποποιεί το έργο υπό τους όρους της άδειας ή που συμβάλλει με άλλον τρόπο στη δημιουργία παράγωγου έργου. +— «Αδειούχος» ή «Εσείς/Σας»:κάθε φυσικό ή νομικό πρόσωπο που κάνει οποιαδήποτε χρήση του έργου υπό τους όρους της άδειας. +— «Διανομή» ή «Παρουσίαση στο κοινό»:κάθε πράξη με την οποία πωλούνται, δίνονται, δανείζονται, εκμισθώνονται, διανέμονται, παρουσιάζονται στο κοινό, μεταδίδονται ή με άλλον τρόπο καθίστανται διαθέσιμα, επιγραμμικώς (on-line) ή εκτός σύνδεσης (off-line), αντίγραφα του έργου ή παρέχεται πρόσβαση στις λειτουργικές δυνατότητές του σε τρίτους, φυσικά ή νομικά πρόσωπα. + +2.Δικαιώματα που παραχωρούνται με την άδεια +Με την παρούσα άδεια, ο χορηγός της άδειας σάς παραχωρεί για όλη τη διάρκεια προστασίας της πνευματικής ιδιοκτησίας επί του πρωτότυπου έργου άδεια παγκόσμιας ισχύος, μη αποκλειστική, χωρίς καταβολή τελών εκμετάλλευσης πνευματικών δικαιωμάτων, δυνάμενη να εκχωρηθεί περαιτέρω, με την οποία μπορείτε: +— να χρησιμοποιείτε το έργο σε κάθε περίσταση και για όλες τις χρήσεις, +— να αναπαράγετε το έργο, +— να τροποποιείτε το έργο και να δημιουργείτε παράγωγα έργα τα οποία βασίζονται στο έργο, +— να παρουσιάζετε το έργο στο κοινό, συμπεριλαμβανομένου του δικαιώματος διάθεσης ή έκθεσης του έργου ή αντιγράφων του στο κοινό και να προβαίνετε, κατά περίπτωση, σε δημόσια εκτέλεσή του, +— να διανέμετε το έργο ή αντίγραφά του, +— να δανείζετε και να εκμισθώνετε το έργο ή αντίγραφά του, +— να εκχωρείτε περαιτέρω δικαιώματα άδειας επί του έργου ή επί αντιγράφων του. +Τα δικαιώματα αυτά μπορούν να ασκηθούν σε κάθε μέσο, υλικό υπόστρωμα και μορφότυπο, που είτε είναι ήδη γνωστά είτε θα επινοηθούν στο μέλλον, εφόσον αυτό δεν προσκρούει στο εφαρμοστέο δίκαιο. Στις χώρες όπου η νομοθεσία αναγνωρίζει ηθικό δικαίωμα επί του έργου, ο χορηγός της άδειας παραιτείται από την άσκηση του οικείου ηθικού δικαιώματος, στον βαθμό που επιτρέπεται από τη νομοθεσία, ώστε η χορήγηση άδειας επί των προαναφερθέντων περιουσιακών δικαιωμάτων να παράγει πλήρως αποτελέσματα. Ο χορηγός της άδειας παραχωρεί στον αδειούχο, χωρίς καταβολή τελών εκμετάλλευσης, μη αποκλειστικά δικαιώματα χρήσης κάθε διπλώματος ευρεσιτεχνίας που ο πρώτος κατέχει, στον βαθμό που είναι αναγκαίος για την άσκηση των δικαιωμάτων που χορηγούνται επί του έργου υπό τους όρους της παρούσας άδειας. +3.Παρουσίαση του πηγαίου κώδικα στο κοινό +Ο χορηγός της άδειας δύναται να διαθέτει το έργο είτε υπό μορφή πηγαίου κώδικα είτε υπό μορφή εκτελέσιμου κώδικα. Εφόσον το έργο διατίθεται ως εκτελέσιμος κώδικας, ο χορηγός της άδειας, μαζί με κάθε αντίγραφο του έργου που διανέμει, παρέχει επιπρόσθετα μηχαναγνώσιμο αντίγραφο του πηγαίου κώδικα του έργου ή υποδεικνύει, σε σημείωση που ακολουθεί την ανακοίνωση σχετικά με τα πνευματικά δικαιώματα που επισυνάπτεται στο έργο, αποθετήριο όπου είναι εύκολα και ελεύθερα προσπελάσιμος ο πηγαίος κώδικας για όσο χρονικό διάστημα ο χορηγός της άδειας εξακολουθεί να διανέμει ή να παρουσιάζει το έργο στο κοινό. +4.Περιορισμοί του δικαιώματος πνευματικής ιδιοκτησίας +Η παρούσα άδεια σε καμία περίπτωση δεν έχει σκοπό να στερήσει τον αδειούχο από τη δυνατότητα να επωφεληθεί από οποιαδήποτε εξαίρεση ή περιορισμό των αποκλειστικών δικαιωμάτων των δικαιούχων επί του έργου, από την ανάλωση των εν λόγω δικαιωμάτων ή από άλλους εφαρμοστέους περιορισμούς. + +5.Υποχρεώσεις του αδειούχου +Η χορήγηση άδειας εκμετάλλευσης των ανωτέρω περιγραφόμενων δικαιωμάτων υπόκειται σε ορισμένους περιορισμούς και υποχρεώσεις που επιβάλλονται στον αδειούχο. Οι υποχρεώσεις αυτές είναι οι ακόλουθες: + +Δικαίωμα μνείας: Ο αδειούχος τηρεί αμετάβλητες όλες τις ανακοινώσεις που αναφέρονται στα πνευματικά δικαιώματα, τα διπλώματα ευρεσιτεχνίας ή τα εμπορικά σήματα, καθώς και όλες τις ανακοινώσεις που αναφέρονται στην άδεια και στη μη παροχή εγγυήσεων. Ο αδειούχος πρέπει να συμπεριλαμβάνει αντίγραφο των ανακοινώσεων και της άδειας σε κάθε αντίγραφο του έργου που διανέμει ή παρουσιάζει στο κοινό. Ο αδειούχος φροντίζει ώστε κάθε παράγωγο έργο να φέρει εμφανή ανακοίνωση όπου θα δηλώνεται ότι το έργο έχει υποστεί τροποποίηση καθώς και την ημερομηνία της τροποποίησης. + +Ρήτρα «Copyleft»: Αν ο αδειούχος διανέμει ή παρουσιάζει στο κοινό αντίγραφα του πρωτότυπου έργου ή των παραγώγων έργων, η εν λόγω διανομή ή παρουσίαση πραγματοποιείται υπό τους όρους της παρούσας άδειας ή μεταγενέστερης έκδοσης της παρούσας άδειας, εκτός εάν το πρωτότυπο έργο διανέμεται ρητά μόνο βάσει της παρούσας έκδοσης της άδειας —για παράδειγμα με τη μνεία «EUPL v. 1.2 μόνον». Ο αδειούχος (όταν καθίσταται χορηγός της άδειας) δεν μπορεί να προσφέρει ή να επιβάλει συμπληρωματικούς όρους ή προϋποθέσεις στο έργο και στο παράγωγο έργο που αλλοιώνουν ή περιορίζουν τους όρους της άδειας. + +Ρήτρα συμβατότητας: Αν ο αδειούχος διανέμει ή παρουσιάζει στο κοινό παράγωγα έργα ή αντίγραφά τους βασισμένα τόσο στο έργο όσο και σε άλλο έργο που έχει αδειοδοτηθεί δυνάμει συμβατής άδειας, μπορεί αυτή η διανομή ή παρουσίαση να πραγματοποιηθεί υπό τους όρους της εν λόγω συμβατής άδειας. Για τους σκοπούς της παρούσας ρήτρας, ο όρος «συμβατή άδεια» αναφέρεται στις άδειες που παρατίθενται στο προσάρτημα που επισυνάπτεται στην παρούσα άδεια. Σε περίπτωση που οι υποχρεώσεις του αδειούχου βάσει της συμβατής άδειας έρχονται σε σύγκρουση με τις υποχρεώσεις του στο πλαίσιο της παρούσας άδειας, υπερισχύουν οι υποχρεώσεις της συμβατής άδειας. + +Διάθεση του πηγαίου κώδικα: Όταν ο αδειούχος διανέμει ή παρουσιάζει στο κοινό αντίγραφα του έργου, παρέχει ένα αναγνώσιμο από ηλεκτρονικό υπολογιστή αντίγραφο του πηγαίου κώδικα ή υποδεικνύει αποθετήριο όπου ο εν λόγω κώδικας διατίθεται εύκολα και ελεύθερα καθ' όλο το χρονικό διάστημα κατά το οποίο ο αδειούχος θα εξακολουθεί να διανέμει ή να παρουσιάζει το έργο. + +Νομική προστασία: Η παρούσα άδεια δεν παρέχει δικαίωμα χρήσης των εμπορικών επωνυμιών, των εμπορικών σημάτων, των υπηρεσιακών σημάτων ή των ονομάτων του χορηγού της άδειας, εκτός εάν, σύμφωνα με εύλογες και συνήθεις πρακτικές, απαιτείται μνεία της προέλευσης του έργου και αναπαραγωγή του περιεχομένου της ανακοίνωσης σχετικά με τα πνευματικά δικαιώματα. + +6.Διαδοχικοί δημιουργοί +Ο αρχικός χορηγός της άδειας εγγυάται ότι τα πνευματικά δικαιώματα επί του πρωτότυπου έργου που παραχωρούνται με την παρούσα άδεια ανήκουν σε αυτόν ή ότι του έχει δοθεί σχετική άδεια και ότι έχει την εξουσία και την ικανότητα να τα παραχωρήσει υπό την παρούσα άδεια. Κάθε συντελεστής εγγυάται ότι τα πνευματικά δικαιώματα επί των τροποποιήσεων που επιφέρει στο έργο ανήκουν σε αυτόν ή ότι του έχει δοθεί σχετική άδεια και ότι έχει την εξουσία και την ικανότητα να τα παραχωρήσει υπό την παρούσα άδεια. Κάθε φορά που αποδέχεστε την άδεια, ο αρχικός χορηγός της άδειας και οι διαδοχικοί συντελεστές Σας παραχωρούν άδεια για τα τμήματα με τα οποία έχουν συμβάλει στο έργο, υπό τους όρους της παρούσας άδειας. + +7.Μη παροχή εγγύησης +Το έργο τελεί υπό εξέλιξη, βελτιούμενο συνεχώς με τη συμβολή πολυάριθμων συντελεστών. Δεν πρόκειται για ολοκληρωμένο έργο και κατά συνέπεια ενδέχεται να περιέχει ελαττώματα ή «σφάλματα», εγγενή σε αυτόν τον τύπο ανάπτυξης. Για τον λόγο αυτόν, το έργο παραδίδεται υπό τους όρους της άδειας «ως έχει» και χωρίς οποιαδήποτε εγγύηση ως προς το έργο, συμπεριλαμβανομένων, ενδεικτικά, της εμπορευσιμότητας, της καταλληλότητάς του για συγκεκριμένο σκοπό, της απουσίας ελαττωμάτων ή σφαλμάτων, της ακρίβειάς του ή της μη προσβολής δικαιωμάτων διανοητικής ιδιοκτησίας άλλων πλην του δικαιώματος πνευματικής ιδιοκτησίας, όπως ορίζεται στο σημείο 6 της παρούσας άδειας. Η παρούσα δήλωση για μη παροχή εγγύησης αποτελεί συστατικό στοιχείο της άδειας και συνιστά όρο για τη χορήγηση άδειας εκμετάλλευσης οποιουδήποτε δικαιώματος επί του έργου. + +8.Μη παροχή εγγύησης +Εκτός από περιπτώσεις ζημιών που προκλήθηκαν εκ προθέσεως ή ζημιών που προκλήθηκαν άμεσα σε φυσικά πρόσωπα, ο χορηγός της άδειας σε καμία περίπτωση δεν φέρει ευθύνη για οποιεσδήποτε, άμεσες ή έμμεσες, υλικές ή ηθικές ζημίες οι οποίες προκύπτουν από την άδεια ή από τη χρήση του έργου, συμπεριλαμβανομένων, ενδεικτικά, ζημιών από την απώλεια φήμης ή πελατείας, από διακοπή εργασιών, από βλάβη ή δυσλειτουργία υπολογιστών, από απώλεια δεδομένων ή από οποιαδήποτε εμπορική ζημία, ακόμα και σε περίπτωση που ο χορηγός της άδειας ήταν ενήμερος σχετικά με την πιθανότητα πρόκλησης τέτοιων ζημιών. Ωστόσο, ο χορηγός της άδειας είναι υπεύθυνος βάσει της νομοθεσίας για την ευθύνη σχετικά με ελαττωματικά προϊόντα, εφόσον η νομοθεσία αυτή εφαρμόζεται στο έργο. + +9.Συμπληρωματικές συμβάσεις +Κατά τη διανομή του έργου, δύναστε να επιλέξετε τη σύναψη συμπληρωματικής σύμβασης, καθορίζοντας υποχρεώσεις ή υπηρεσίες συμβατές με την παρούσα άδεια. Ωστόσο, εφόσον αποδέχεστε υποχρεώσεις, ενεργείτε αποκλειστικά για λογαριασμό Σας και υπ' ευθύνη Σας και όχι για λογαριασμό του αρχικού χορηγού της άδειας ή οποιουδήποτε άλλου συντελεστή και μόνον εφόσον συμφωνείτε να αποζημιώσετε, να υπερασπιστείτε και να απαλλάξετε κάθε συντελεστή από οποιαδήποτε ευθύνη υπέχει ή από τη διεκδίκηση απαιτήσεων έναντί του εξαιτίας του ότι έχετε αποδεχθεί εγγύηση ή έχετε αναλάβει συμπληρωματική ευθύνη. + +10.Αποδοχή της άδειας +Μπορείτε να αποδεχθείτε τους όρους της παρούσας άδειας πατώντας το πλήκτρο στο εικονίδιο «συμφωνώ», που βρίσκεται στο κάτω μέρος ενός παραθύρου όπου εμφανίζεται το κείμενο της παρούσας άδειας ή επιβεβαιώνοντας τη συναίνεσή σας με οποιονδήποτε άλλο παρεμφερή τρόπο, σύμφωνα με τους κανόνες του εφαρμοστέου δικαίου. Εφόσον πατήσετε το εικονίδιο αυτό, δηλώνετε τη σαφή και ανέκκλητη αποδοχή εκ μέρους σας της παρούσας άδειας και όλων των όρων και προϋποθέσεών της. Παρομοίως, αποδέχεστε ανέκκλητα την παρούσα άδεια και το σύνολο των όρων και προϋποθέσεών της εφόσον ασκήσετε οποιοδήποτε δικαίωμα Σας έχει χορηγηθεί βάσει του σημείου 2 της παρούσας άδειας, όπως όταν κάνετε χρήση του έργου, δημιουργείτε παράγωγο έργο ή διανέμετε ή παρουσιάζετε το έργο ή αντίγραφά του. + +11.Πληροφόρηση του κοινού +Εφόσον διανέμετε ή παρουσιάζετε το έργο με ηλεκτρονικά μέσα επικοινωνίας (όταν π.χ. επιτρέπετε την τηλεφόρτωση του έργου από ιστότοπο), πρέπει το κανάλι ή το μέσο διανομής (π.χ. ένας ιστότοπος) να παρέχει στο κοινό τουλάχιστον τις πληροφορίες που απαιτούνται από το εφαρμοστέο δίκαιο όσον αφορά τον χορηγό της άδειας, την άδεια, καθώς και τον τρόπο με τον οποίο είναι δυνατές η προσπέλαση στην άδεια, η σύναψή της, η αποθήκευση και η αναπαραγωγή της από τον αδειούχο. + +12.Λήξη ισχύος της άδειας +Η άδεια και τα δικαιώματα που έχουν παραχωρηθεί υπό τους όρους αυτής λήγουν αυτοδικαίως με την παραβίαση εκ μέρους του αδειούχου οποιουδήποτε από τους όρους της άδειας. Η λήξη αυτή δεν συνεπάγεται λήξη των αδειών των ατόμων στα οποία το έργο έχει περιέλθει από τον αδειούχο υπό τους όρους της άδειας, υπό την προϋπόθεση ότι τα άτομα αυτά εξακολουθούν να τηρούν τους όρους της άδειας. + +13.Διάφορα +Με την επιφύλαξη του σημείου 9, η άδεια αποτυπώνει την πλήρη συμφωνία μεταξύ των μερών ως προς το έργο. Αν, βάσει του εφαρμοστέου δικαίου, οποιαδήποτε ρήτρα της άδειας καθίσταται άκυρη ή ανεκτέλεστη, τούτο δεν επηρεάζει την ισχύ ή τη δυνατότητα εκτέλεσης της άδειας στο σύνολό της. H εν λόγω ρήτρα ερμηνεύεται ή αναδιατυπώνεται στο αναγκαίο μέτρο ώστε να καταστεί έγκυρη και εκτελεστή. H Ευρωπαϊκή Επιτροπή δύναται να δημοσιεύσει άλλες γλωσσικές αποδόσεις ή νέες εκδόσεις της παρούσας άδειας ή επικαιροποιημένες εκδόσεις του προσαρτήματος, εφόσον τούτο είναι απαραίτητο και εύλογο, χωρίς να περιορίζει τα δικαιώματα που παραχωρούνται με την άδεια. Οι νέες εκδόσεις της άδειας θα δημοσιεύονται με αποκλειστικό αριθμό έκδοσης. Όλες οι γλωσσικές αποδόσεις της παρούσας άδειας που έχουν εγκριθεί από την Ευρωπαϊκή Επιτροπή έχουν ισοδύναμη αξία. Τα μέρη μπορούν να επικαλεστούν τη γλωσσική απόδοση της επιλογής τους. + +14.Δικαιοδοσία +Με την επιφύλαξη ειδικής συμφωνίας μεταξύ των μερών, — κάθε διαφορά που ανακύπτει από την ερμηνεία της παρούσας άδειας, μεταξύ των θεσμικών και λοιπών οργάνων και οργανισμών της Ευρωπαϊκής Ένωσης ως χορηγού της άδειας και οποιουδήποτε αδειούχου, υπάγεται στη δικαιοδοσία του Δικαστηρίου της Ευρωπαϊκής Ένωσης, όπως ορίζει το άρθρο 272 της Συνθήκης για τη λειτουργία της Ευρωπαϊκής Ένωσης, — κάθε διαφορά μεταξύ άλλων μερών η οποία ανακύπτει από την ερμηνεία της παρούσας άδειας υπάγεται στην αποκλειστική δικαιοδοσία του αρμόδιου δικαστηρίου όπου ο αδειούχος έχει την κατοικία του ή ασκεί την κύρια δραστηριότητά του. + +15.Εφαρμοστέο δίκαιο +Με την επιφύλαξη ειδικής συμφωνίας μεταξύ των μερών, — η παρούσα άδεια διέπεται από το δίκαιο της χώρας της Ευρωπαϊκής Ένωσης στην οποία ο αδειούχος έχει την έδρα του, την κατοικία του ή την καταστατική έδρα του, — η παρούσα άδεια διέπεται από το βελγικό δίκαιο εάν ο αδειούχος δεν έχει έδρα, κατοικία ή καταστατική έδρα εντός κράτους μέλους της Ευρωπαϊκής Ένωσης. + +Προσάρτημα +«Συμβατές άδειες» βάσει του άρθρου 5 της EUPL είναι οι: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) για έργα πλην λογισμικού +— European Union Public Licence (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence — αμοιβαιότητα (LiLiQ-R) ή ισχυρή αμοιβαιότητα (LiLiQ-R+) +Η Ευρωπαϊκή Επιτροπή δύναται να επικαιροποιεί το εν λόγω προσάρτημα με μεταγενέστερες εκδόσεις των παραπάνω αδειών, χωρίς να παράγει νέα έκδοση της EUPL, εφόσον οι άδειες παρέχουν τα δικαιώματα που αναγνωρίζονται στο άρθρο 2 της παρούσας άδειας και προστατεύουν τον καλυπτόμενο από αυτές πηγαίο κώδικα από αποκλειστική ιδιοποίηση. +Όλες οι άλλες αλλαγές ή προσθήκες στο παρόν προσάρτημα απαιτούν τη δημιουργία νέας έκδοσης EUPL. 19.5.2017 L 128/64 Επίσηµη Εφηµερίδα της Ευρωπαϊκής Ένωσης EL diff --git a/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 EN.txt b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 EN.txt new file mode 100644 index 0000000..4153cd3 --- /dev/null +++ b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 EN.txt @@ -0,0 +1,287 @@ + EUROPEAN UNION PUBLIC LICENCE v. 1.2 + EUPL © the European Union 2007, 2016 + +This European Union Public Licence (the ‘EUPL’) applies to the Work (as defined +below) which is provided under the terms of this Licence. Any use of the Work, +other than as authorised under this Licence is prohibited (to the extent such +use is covered by a right of the copyright holder of the Work). + +The Work is provided under the terms of this Licence when the Licensor (as +defined below) has placed the following notice immediately following the +copyright notice for the Work: + + Licensed under the EUPL + +or has expressed by any other means his willingness to license under the EUPL. + +1. Definitions + +In this Licence, the following terms have the following meaning: + +- ‘The Licence’: this Licence. + +- ‘The Original Work’: the work or software distributed or communicated by the + Licensor under this Licence, available as Source Code and also as Executable + Code as the case may be. + +- ‘Derivative Works’: the works or software that could be created by the + Licensee, based upon the Original Work or modifications thereof. This Licence + does not define the extent of modification or dependence on the Original Work + required in order to classify a work as a Derivative Work; this extent is + determined by copyright law applicable in the country mentioned in Article 15. + +- ‘The Work’: the Original Work or its Derivative Works. + +- ‘The Source Code’: the human-readable form of the Work which is the most + convenient for people to study and modify. + +- ‘The Executable Code’: any code which has generally been compiled and which is + meant to be interpreted by a computer as a program. + +- ‘The Licensor’: the natural or legal person that distributes or communicates + the Work under the Licence. + +- ‘Contributor(s)’: any natural or legal person who modifies the Work under the + Licence, or otherwise contributes to the creation of a Derivative Work. + +- ‘The Licensee’ or ‘You’: any natural or legal person who makes any usage of + the Work under the terms of the Licence. + +- ‘Distribution’ or ‘Communication’: any act of selling, giving, lending, + renting, distributing, communicating, transmitting, or otherwise making + available, online or offline, copies of the Work or providing access to its + essential functionalities at the disposal of any other natural or legal + person. + +2. Scope of the rights granted by the Licence + +The Licensor hereby grants You a worldwide, royalty-free, non-exclusive, +sublicensable licence to do the following, for the duration of copyright vested +in the Original Work: + +- use the Work in any circumstance and for all usage, +- reproduce the Work, +- modify the Work, and make Derivative Works based upon the Work, +- communicate to the public, including the right to make available or display + the Work or copies thereof to the public and perform publicly, as the case may + be, the Work, +- distribute the Work or copies thereof, +- lend and rent the Work or copies thereof, +- sublicense rights in the Work or copies thereof. + +Those rights can be exercised on any media, supports and formats, whether now +known or later invented, as far as the applicable law permits so. + +In the countries where moral rights apply, the Licensor waives his right to +exercise his moral right to the extent allowed by law in order to make effective +the licence of the economic rights here above listed. + +The Licensor grants to the Licensee royalty-free, non-exclusive usage rights to +any patents held by the Licensor, to the extent necessary to make use of the +rights granted on the Work under this Licence. + +3. Communication of the Source Code + +The Licensor may provide the Work either in its Source Code form, or as +Executable Code. If the Work is provided as Executable Code, the Licensor +provides in addition a machine-readable copy of the Source Code of the Work +along with each copy of the Work that the Licensor distributes or indicates, in +a notice following the copyright notice attached to the Work, a repository where +the Source Code is easily and freely accessible for as long as the Licensor +continues to distribute or communicate the Work. + +4. Limitations on copyright + +Nothing in this Licence is intended to deprive the Licensee of the benefits from +any exception or limitation to the exclusive rights of the rights owners in the +Work, of the exhaustion of those rights or of other applicable limitations +thereto. + +5. Obligations of the Licensee + +The grant of the rights mentioned above is subject to some restrictions and +obligations imposed on the Licensee. Those obligations are the following: + +Attribution right: The Licensee shall keep intact all copyright, patent or +trademarks notices and all notices that refer to the Licence and to the +disclaimer of warranties. The Licensee must include a copy of such notices and a +copy of the Licence with every copy of the Work he/she distributes or +communicates. The Licensee must cause any Derivative Work to carry prominent +notices stating that the Work has been modified and the date of modification. + +Copyleft clause: If the Licensee distributes or communicates copies of the +Original Works or Derivative Works, this Distribution or Communication will be +done under the terms of this Licence or of a later version of this Licence +unless the Original Work is expressly distributed only under this version of the +Licence — for example by communicating ‘EUPL v. 1.2 only’. The Licensee +(becoming Licensor) cannot offer or impose any additional terms or conditions on +the Work or Derivative Work that alter or restrict the terms of the Licence. + +Compatibility clause: If the Licensee Distributes or Communicates Derivative +Works or copies thereof based upon both the Work and another work licensed under +a Compatible Licence, this Distribution or Communication can be done under the +terms of this Compatible Licence. For the sake of this clause, ‘Compatible +Licence’ refers to the licences listed in the appendix attached to this Licence. +Should the Licensee's obligations under the Compatible Licence conflict with +his/her obligations under this Licence, the obligations of the Compatible +Licence shall prevail. + +Provision of Source Code: When distributing or communicating copies of the Work, +the Licensee will provide a machine-readable copy of the Source Code or indicate +a repository where this Source will be easily and freely available for as long +as the Licensee continues to distribute or communicate the Work. + +Legal Protection: This Licence does not grant permission to use the trade names, +trademarks, service marks, or 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 copyright notice. + +6. Chain of Authorship + +The original Licensor warrants that the copyright in the Original Work granted +hereunder is owned by him/her or licensed to him/her and that he/she has the +power and authority to grant the Licence. + +Each Contributor warrants that the copyright in the modifications he/she brings +to the Work are owned by him/her or licensed to him/her and that he/she has the +power and authority to grant the Licence. + +Each time You accept the Licence, the original Licensor and subsequent +Contributors grant You a licence to their contributions to the Work, under the +terms of this Licence. + +7. Disclaimer of Warranty + +The Work is a work in progress, which is continuously improved by numerous +Contributors. It is not a finished work and may therefore contain defects or +‘bugs’ inherent to this type of development. + +For the above reason, the Work is provided under the Licence on an ‘as is’ basis +and without warranties of any kind concerning the Work, including without +limitation merchantability, fitness for a particular purpose, absence of defects +or errors, accuracy, non-infringement of intellectual property rights other than +copyright as stated in Article 6 of this Licence. + +This disclaimer of warranty is an essential part of the Licence and a condition +for the grant of any rights to the Work. + +8. Disclaimer of Liability + +Except in the cases of wilful misconduct or damages directly caused to natural +persons, the Licensor will in no event be liable for any direct or indirect, +material or moral, damages of any kind, arising out of the Licence or of the use +of the Work, including without limitation, damages for loss of goodwill, work +stoppage, computer failure or malfunction, loss of data or any commercial +damage, even if the Licensor has been advised of the possibility of such damage. +However, the Licensor will be liable under statutory product liability laws as +far such laws apply to the Work. + +9. Additional agreements + +While distributing the Work, You may choose to conclude an additional agreement, +defining obligations or services consistent with this Licence. However, if +accepting obligations, You may act only on your own behalf and on your sole +responsibility, not on behalf of the original Licensor or 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 +the fact You have accepted any warranty or additional liability. + +10. Acceptance of the Licence + +The provisions of this Licence can be accepted by clicking on an icon ‘I agree’ +placed under the bottom of a window displaying the text of this Licence or by +affirming consent in any other similar way, in accordance with the rules of +applicable law. Clicking on that icon indicates your clear and irrevocable +acceptance of this Licence and all of its terms and conditions. + +Similarly, you irrevocably accept this Licence and all of its terms and +conditions by exercising any rights granted to You by Article 2 of this Licence, +such as the use of the Work, the creation by You of a Derivative Work or the +Distribution or Communication by You of the Work or copies thereof. + +11. Information to the public + +In case of any Distribution or Communication of the Work by means of electronic +communication by You (for example, by offering to download the Work from a +remote location) the distribution channel or media (for example, a website) must +at least provide to the public the information requested by the applicable law +regarding the Licensor, the Licence and the way it may be accessible, concluded, +stored and reproduced by the Licensee. + +12. Termination of the Licence + +The Licence and the rights granted hereunder will terminate automatically upon +any breach by the Licensee of the terms of the Licence. + +Such a termination will not terminate the licences of any person who has +received the Work from the Licensee under the Licence, provided such persons +remain in full compliance with the Licence. + +13. Miscellaneous + +Without prejudice of Article 9 above, the Licence represents the complete +agreement between the Parties as to the Work. + +If any provision of the Licence is invalid or unenforceable under applicable +law, this will not affect the validity or enforceability of the Licence as a +whole. Such provision will be construed or reformed so as necessary to make it +valid and enforceable. + +The European Commission may publish other linguistic versions or new versions of +this Licence or updated versions of the Appendix, so far this is required and +reasonable, without reducing the scope of the rights granted by the Licence. New +versions of the Licence will be published with a unique version number. + +All linguistic versions of this Licence, approved by the European Commission, +have identical value. Parties can take advantage of the linguistic version of +their choice. + +14. Jurisdiction + +Without prejudice to specific agreement between parties, + +- any litigation resulting from the interpretation of this License, arising + between the European Union institutions, bodies, offices or agencies, as a + Licensor, and any Licensee, will be subject to the jurisdiction of the Court + of Justice of the European Union, as laid down in article 272 of the Treaty on + the Functioning of the European Union, + +- any litigation arising between other parties and resulting from the + interpretation of this License, will be subject to the exclusive jurisdiction + of the competent court where the Licensor resides or conducts its primary + business. + +15. Applicable Law + +Without prejudice to specific agreement between parties, + +- this Licence shall be governed by the law of the European Union Member State + where the Licensor has his seat, resides or has his registered office, + +- this licence shall be governed by Belgian law if the Licensor has no seat, + residence or registered office inside a European Union Member State. + +Appendix + +‘Compatible Licences’ according to Article 5 EUPL are: + +- GNU General Public License (GPL) v. 2, v. 3 +- GNU Affero General Public License (AGPL) v. 3 +- Open Software License (OSL) v. 2.1, v. 3.0 +- Eclipse Public License (EPL) v. 1.0 +- CeCILL v. 2.0, v. 2.1 +- Mozilla Public Licence (MPL) v. 2 +- GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +- Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for + works other than software +- European Union Public Licence (EUPL) v. 1.1, v. 1.2 +- Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong + Reciprocity (LiLiQ-R+). + +The European Commission may update this Appendix to later versions of the above +licences without producing a new version of the EUPL, as long as they provide +the rights granted in Article 2 of this Licence and protect the covered Source +Code from exclusive appropriation. + +All other changes or additions to this Appendix require the production of a new +EUPL version. diff --git a/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 ES.txt b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 ES.txt new file mode 100644 index 0000000..5ba4ab2 --- /dev/null +++ b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 ES.txt @@ -0,0 +1,95 @@ +LICENCIA PÚBLICA DE LA UNIÓN EUROPEA v. 1.2 +EUPL © Unión Europea 2007, 2016 +La presente Licencia Pública de la Unión Europea (EUPL, por su sigla en inglés), se aplica a la obra (según se define más adelante) suministrada en las condiciones fijadas en la presente licencia. Queda prohibido cualquier uso de la obra distinto del autorizado por la presente licencia (en la medida en que tal uso esté protegido por un derecho del titular de los derechos de autor de la obra). La obra se suministra en las condiciones fijadas en la presente licencia cuando el licenciante (según se define más adelante) haya colocado la siguiente advertencia inmediatamente después de la mención a los derechos de autor de la obra: + Licencia cedida con arreglo a la EUPL +o haya expresado por cualquier otro medio su voluntad de conceder una licencia con arreglo a la EUPL. + +1.Definiciones +En la presente licencia, se entenderá por: +— «licencia»:la presente licencia, +— «obra original»:la obra o el programa de ordenador distribuido o comunicado por el licenciante con arreglo a la presente licencia en forma de código fuente o, en su caso, de código ejecutable, +— «obras derivadas»:las obras o programas de ordenador que pudiera crear el licenciatario sobre la base de la obra original o de alguna de las modificaciones de esta. La presente licencia no define el grado de modificación o dependencia de la obra original necesario para clasificar una obra como derivada; dicho grado se determinará de acuerdo con la legislación sobre derechos de autor aplicable con arreglo al artículo 15, +— «obra»:la obra original o sus obras derivadas, +— «código fuente»:la forma de la obra legible por seres humanos que pueda ser estudiada y modificada más fácilmente, +— «código ejecutable»:cualquier código, en general compilado, destinado a ser interpretado como programa por un ordenador, +— «licenciante»:la persona física o jurídica que distribuye o comunica la obra con arreglo a la licencia, +— «colaborador»:la persona física o jurídica que modifica la obra con arreglo a la licencia o contribuye de cualquier otra manera a crear una obra derivada, +— «licenciatario»:la persona física o jurídica que hace un uso cualquiera de la obra en las condiciones fijadas en la licencia, +— «distribución» o «comunicación»:cualquier acto de venta, donación, préstamo, alquiler, distribución, comunicación, transmisión o cualquier otro acto de puesta a disposición, en línea o fuera de línea, de copias de la obra o de acceso a sus funcionalidades esenciales a otra persona física o jurídica. + +2.Ámbito de los derechos otorgados por la Licencia +El licenciante concede al licenciatario una licencia de ámbito mundial, a título gratuito, no exclusiva y que el licenciatario puede subcontratar mientras sigan vigentes los derechos de autor sobre la obra original, y lo autoriza a: +— utilizar la obra en cualquier circunstancia y para cualquier uso, +— reproducir la obra, +— modificar la obra y realizar obras derivadas de la misma, +— comunicar al público la obra o copias de la misma, poner a su disposición o exhibir la obra o las copias y, en su caso, ejecutar públicamente la obra, +— distribuir la obra o copias de la misma, +— prestar y alquilar la obra o copias de la misma, +— subcontratar los derechos relativos a la obra o a las copias de la misma. +Dichos derechos se podrán ejercer a través de cualquier medio, soporte y formato, conocido en el presente o que pueda inventarse en el futuro, en la medida en que así lo permita la legislación aplicable. En los países cuyo ordenamiento contemple los derechos morales, el licenciante renunciará al ejercicio de los mismos en la medida en que lo permita la legislación, a fin de hacer efectiva la licencia de los derechos patrimoniales anteriormente enumerados. El licenciante cede al licenciatario, libre de cánones, los derechos de uso no exclusivos sobre cualquier patente de que sea titular, en la medida necesaria para que el licenciatario haga uso de los derechos sobre la obra otorgados por la presente licencia. + +3.Comunicación del código fuente +El licenciante podrá suministrar la obra en forma de código fuente o código ejecutable. Si la suministrara en forma de código ejecutable, deberá facilitar además una copia legible automáticamente del código fuente de la obra junto con cada copia de la obra que distribuya, o bien indicar, en una advertencia inserta a continuación de la mención a los derechos de autor adjunta a la obra, un repositorio en el que se pueda acceder al código fuente fácilmente y de manera gratuita durante el período en que el licenciante siga distribuyendo o comunicando la obra. + +4.Limitaciones a los derechos de autor +En ningún caso podrá interpretarse la presente licencia de modo que prive al licenciatario de los beneficios de los que pudiera disfrutar como consecuencia de las excepciones o limitaciones a los derechos exclusivos de los titulares de los derechos de la obra, de la extinción de dichos derechos o de cualquier otra limitación aplicable. + +5.Obligaciones del licenciatario +La cesión de los derechos en virtud de la presente licencia queda supeditada a ciertas restricciones u obligaciones que habrá de respetar el licenciatario. Dichas obligaciones son: + +Derecho de atribución: El licenciatario deberá mantener íntegramente todas las advertencias y menciones a los derechos de autor, patentes o marcas registradas, así como las que se refieran a la licencia y a la exención de responsabilidad. El licenciatario deberá adjuntar copias de dichas advertencias y menciones y de la licencia con cada copia de la obra que distribuya o comunique. El licenciatario se responsabilizará de que cualquier obra derivada incluya una advertencia bien destacada declarando que se ha modificado la obra, y la fecha de modificación. + +Cláusula de «copyleft»: Si el licenciatario distribuyera o comunicara copias de la obra original o de obras derivadas basadas en la obra original, dicha distribución o comunicación deberá hacerse en las condiciones fijadas en la presente licencia o una versión posterior de la presente licencia, salvo si la obra original se distribuye expresamente solo bajo la presente versión de la licencia (por ejemplo, comunicando «EUPL v. 1.2 solamente». El licenciatario (ahora en su calidad de licenciante) no podrá ofrecer ni imponer condiciones adicionales sobre la obra o las obras derivadas que modifiquen o limiten las condiciones de la licencia. + +Cláusula de compatibilidad: Si el licenciatario distribuyera o comunicara obras derivadas o copias de estas últimas basadas a su vez en la obra y en otra obra licenciada bajo una licencia compatible, la distribución o comunicación podrán efectuarse con arreglo a las condiciones de dicha licencia compatible. A efectos de la presente cláusula, se entenderá por «licencia compatible» cualquiera de las licencias enumeradas en el apéndice adjunto a la presente licencia. En caso de que las obligaciones del licenciatario con arreglo a la licencia compatible estén en colisión con las derivadas de la presente licencia, prevalecerán las obligaciones de la licencia compatible. + +Suministro del código fuente: Cuando distribuya o comunique copias de la obra, el licenciatario deberá facilitar una copia del código fuente legible automáticamente o indicar un repositorio en que se pueda acceder al código fuente fácilmente y de manera gratuita durante el período en que siga distribuyendo o comunicando la obra. + +Salvaguardia de otros derechos: La presente licencia no faculta para utilizar los nombres comerciales, marcas de producto o de servicio o nombres del licenciante, excepto cuando ello, realizado en la medida de lo razonable y conforme a los usos habituales, sea necesario para indicar el origen de la obra y reproducir el contenido de la mención a los derechos de autor. + +6.Secuencia de autoría +El licenciante original garantiza ser titular originario de los derechos de autor sobre la obra original objeto de la presente licencia o haberlos adquirido mediante la licencia correspondiente y estar facultado para otorgar licencias sobre tales derechos. Cada colaborador garantiza ser titular de los derechos de autor sobre las modificaciones que aporta a la obra o haberlos adquirido mediante la correspondiente licencia y estar facultado para otorgar licencias sobre tales derechos. Cada vez que el licenciatario acepta la licencia, el licenciante original y los colaboradores posteriores le otorgan una licencia sobre sus propias contribuciones a la obra en las condiciones fijadas en la presente licencia. + +7.Exclusión de garantía +La obra se encuentra en proceso de elaboración, siendo objeto de continuas mejoras por parte de numerosos colaboradores. No es una obra acabada y, por tanto, puede contener defectos o fallos inherentes a este tipo de desarrollo. Por este motivo, la obra, en virtud de la licencia, se suministra «tal cual», sin garantías de ningún tipo, en particular, en una enumeración no exhaustiva, en cuanto a su comercialización, adecuación a un propósito determinado, ausencia de defectos o errores, exactitud y ausencia de infracción de los derechos de propiedad intelectual distintos de los derechos de autor según se afirma en el artículo 6 de la presente licencia. Esta exclusión de garantía forma parte esencial de la licencia y es condición para la cesión de cualquier derecho con respecto a la obra. +8.Exclusión de responsabilidad +Excepto en casos de dolo o de daños ocasionados directamente a personas físicas, el licenciante no será responsable de los daños y perjuicios de cualquier clase, directos o indirectos, materiales o morales, que pudieran derivarse de la licencia o del uso de la obra, en particular, en una enumeración no exhaustiva, de los daños y perjuicios por pérdida de buena reputación, paro técnico, avería o mal funcionamiento de equipos informáticos, pérdida de datos o cualquier perjuicio comercial, incluso si el licenciante conocía la posibilidad de dichos daños. No obstante, el licenciante será responsable, de acuerdo con las normas legales que regulen la responsabilidad por los daños causados por productos, en la medida en que dichas normas sean aplicables a la obra. + +9.Acuerdos adicionales +Al distribuir la obra, el licenciatario podrá suscribir un acuerdo adicional que defina obligaciones o servicios compatibles con la presente licencia. No obstante, al aceptar tales obligaciones, el licenciatario actuará únicamente en nombre propio y bajo su exclusiva responsabilidad, y nunca en nombre del licenciante original ni de ningún otro colaborador, y ello a condición de que acceda a indemnizar, defender y amparar a todo colaborador frente a cualquier responsabilidad en que este pudiera incurrir y frente a las reclamaciones que pudieran presentarse contra él por haber aceptado el licenciatario la mencionada garantía o responsabilidad adicional. + +10.Aceptación de la licencia +Lo dispuesto en la presente licencia puede aceptarse haciendo clic en el icono «Aceptar» situado en la parte inferior de la ventana en que aparece el texto de la presente licencia o manifestando el consentimiento de cualquier otra forma similar, de conformidad con lo previsto en la legislación aplicable. Haciendo clic en dicho icono, se expresa la aceptación inequívoca e irrevocable de la presente licencia y de todo su contenido. Asimismo, el licenciatario acepta irrevocablemente la presente licencia y todas sus condiciones por el mero hecho de ejercer cualquiera de los derechos que le otorga el artículo 2 de la presente licencia, tales como el uso de la obra, la creación de una obra derivada o la distribución o comunicación de la obra o de copias de la misma. + +11.Información al público +En caso de que el licenciatario proceda a la distribución o comunicación de la obra por medios electrónicos (por ejemplo, ofreciendo la descarga de la obra a distancia), el canal o medio de distribución (por ejemplo, un sitio web) deberá facilitar al público, como mínimo, la información exigida por la legislación aplicable acerca del licenciante, la licencia y la manera en que el licenciatario puede acceder a dichos datos, aceptarlos, conservarlos y reproducirlos. + +12.Extinción de la licencia +La licencia y los derechos otorgados a su amparo se extinguirán automáticamente si el licenciatario incumple alguna de las condiciones de la licencia. Tal extinción no supondrá, sin embargo, la de las licencias de que disfruten las personas que hayan recibido la obra del licenciatario en virtud de la licencia, siempre que dichas personas sigan cumpliendo plenamente las condiciones de la licencia. + +13.Varios No obstante lo dispuesto en el artículo 9, la licencia representará la totalidad del acuerdo entre las partes en cuanto a la obra. La eventual invalidez o ineficacia de alguna disposición de la presente licencia con arreglo a la legislación vigente no afectará a la validez o eficacia general de la licencia. En tales casos, la disposición se interpretará o reformulará según proceda para hacerla válida y eficaz. La Comisión Europea podrá publicar otras versiones lingüísticas o nuevas versiones de la presente licencia o versiones actualizadas del apéndice en la medida en que resulte necesario y razonable y sin reducir el ámbito de los derechos concedidos por la licencia. Las nuevas versiones de la licencia se publicarán con un número de versión único. Todas las versiones lingüísticas de la presente licencia aprobadas por la Comisión Europea tienen idéntico valor. Las partes pueden utilizar la versión lingüística de su preferencia. + +14.Tribunales competentes +Sin perjuicio de lo dispuesto en un acuerdo específico entre las partes, +— los litigios relativos a la interpretación de la presente licencia que se planteen entre las instituciones, órganos y organismos de la Unión Europea, en calidad de licenciante, y un licenciatario, se someterán a la jurisdicción del Tribunal de Justicia de la Unión Europea, con arreglo al artículo 272 del Tratado de Funcionamiento de la Unión Europea; +— los litigios relativos la interpretación de la presente licencia que se planteen entre otras partes se someterán a la jurisdicción exclusiva del tribunal que sea competente en el lugar en que resida o ejerza su actividad principal el licenciante. + +15.Legislación aplicable +Sin perjuicio de lo dispuesto en un acuerdo específico entre las partes, +— la presente licencia se regirá por la legislación del Estado miembro de la Unión Europea en el que tenga su sede, resida o tenga su domicilio social el licenciante; +— la presente licencia se regirá por el Derecho belga si el licenciante no tiene sede, residencia ni domicilio social en un Estado miembro de la Unión Europea. + +Apéndice +Son «licencias compatibles» con arreglo al artículo 5 de la EUPL: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) para obras que no sean programas informáticos +— European Union Public Licence (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+). +La Comisión Europea podrá actualizar el presente apéndice a versiones posteriores de las licencias mencionadas sin presentar una nueva versión de la EUPL, siempre que contemplen los derechos reconocidos en el artículo 2 de la presente licencia y protejan de la apropiación exclusiva el código fuente cubierto. +Cualquier otra modificación o adición al presente apéndice exigirá la presentación de una nueva versión de la EUPL. 19.5.2017 L 128/64 Diario Oficial de la Unión Europea ES diff --git a/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 ET.txt b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 ET.txt new file mode 100644 index 0000000..93e275d --- /dev/null +++ b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 ET.txt @@ -0,0 +1,97 @@ +EUROOPA LIIDU TARKVARA VABA KASUTUSE LITSENTS v. 1.2 +EUPL © Euroopa Liit 2007, 2016 +Euroopa Liidu tarkvara vaba kasutuse litsents („EUPL“) kehtib allpool määratletud teose suhtes, mida levitatakse vastavalt käesoleva litsentsi tingimustele. Teost on keelatud kasutada muul viisil kui vastavalt käesoleva litsentsi tingimustele niivõrd, kuivõrd sellise kasutamise suhtes kehtivad teose autoriõiguse omaja õigused). Teost levitatakse vastavalt käesoleva litsentsi tingimustele, kui allpool määratletud litsentsiandja paneb vahetult teose autoriõiguse märke järele järgmise märke: + Litsentsitud EUPL alusel +või on muul viisil väljendanud soovi litsentsida originaalteos EUPL alusel. + +1.Mõisted +Käesolevas litsentsis kasutatakse järgmisi mõisteid: +— „litsents“–käesolev litsents; +— „originaalteos“–teos või tarkvara, mida litsentsiandja käesoleva litsentsi alusel levitab või edastab ning mis on kättesaadav lähtekoodina ja teatavatel juhtudel ka täitmiskoodina; +— „tuletatud teos“–teos või tarkvara, mida litsentsisaajal on olnud võimalik luua tuginedes originaalteosele või selle muudetud versioonile. Käesolevas litsentsis ei määratleta muudatuse ulatust või sõltuvust originaalteosest, mis on vajalik selleks, et klassifitseerida teos tuletatud teoseks; selline ulatus määratakse kindlaks vastavalt artiklis 15 nimetatud riigis kehtivatele autoriõigust käsitlevatele õigusaktidele; +— „teos“–originaalteos või sellest tuletatud teosed; +— „lähtekood“–teose inimloetav vorm, mida inimestel on kõige lihtsam uurida ja muuta; +— „täitmiskood“–igasugune kood, mille on tavaliselt koostanud arvuti ja mis on mõeldud arvuti poolt programmina tõlgendamiseks; +— „litsentsiandja“–füüsiline või juriidiline isik, kes levitab või edastab teost litsentsi alusel; +— „edasiarendaja“–füüsiline või juriidiline isik, kes muudab teost litsentsi alusel või osaleb muul moel tuletatud teose loomises; +— „litsentsisaaja“ või „Teie“–iga füüsiline või juriidiline isik, kes kasutab teost ükskõik mis moel vastavalt litsentsi tingimustele; +— „levitamine“ või „edastamine“–teose koopiate müümine, teisele isikule andmine, laenutamine, rentimine, levitamine, edastamine, ülekandmine või teose koopiate või selle oluliste funktsioonide muul viisil teistele füüsilistele või juriidilistele isikutele kättesaadavaks tegemine võrgus või võrguväliselt. + +2.Litsentsiga antavate õiguste ulatus +Käesolevaga annab litsentsiandja Teile ülemaailmse, tasuta, all-litsentsi andmise õigusega lihtlitsentsi, mille alusel võite teha originaalteose autoriõiguse kehtivusaja jooksul järgmist: +— kasutada teost mis tahes eesmärgil ja mis tahes viisil, +— teost reprodutseerida, +— teost muuta ja luua teosel põhinevaid tuletatud teoseid, +— teost või selle koopiaid üldsusele edastada, sealhulgas neid kättesaadavaks teha või eksponeerida, samuti avalikult esitada, +— teost või selle koopiaid levitada, +— teost või selle koopiaid laenutada ja rentida, +— anda all-litsentse teose või selle koopiate suhtes kehtivate õiguste kohta. +Neid õigusi võib teostada mistahes praegu tuntud või hiljem leiutatud keskkonnas, toel või formaadis, ja sellises ulatuses, nagu lubab kohaldatav õigus. Riikides, kus kehtivad isiklikud õigused, loobub litsentsiandja seadusega lubatud ulatuses oma õigusest teostada isiklikke õigusi, et oleks võimalik eespool loetletud varalisi õigusi litsentsida. Litsentsiandja annab litsentsisaajale tasuta lihtlitsentsi kõigi litsentsiandjale kuuluvate patentide kasutamiseks ulatuses, mis on vajalik teose suhtes käesoleva litsentsiga antud õiguste kasutamiseks. + +3.Lähtekoodi edastamine +Litsentsiandja võib teose kättesaadavaks teha kas lähtekoodi või täitmiskoodi kujul. Kui teos tehakse kättesaadavaks täitmiskoodi kujul, lisab litsentsiandja igale tema poolt levitatavale teose koopiale lähtekoodi masinloetava koopia või näitab teose autoriõiguse märke järele lisatud märkega ära hoidla, kust lähtekood on kergesti ja tasuta kättesaadav seni, kuni litsentsiandja jätkab teose levitamist või edastamist. + +4.Autoriõiguse piiramine +Käesolev litsents ei võta litsentsisaajalt võimalusi, mis tulenevad teose õiguste omaja ainuõiguste suhtes kehtestatud eranditest või ainuõiguste piiramisest, nende õiguste ammendumisest või muudest nende õiguste suhtes kohaldatavatest piirangutest. + +5.Litsentsisaaja kohustused +Eespool nimetatud õigused antakse litsentsisaajale tingimusel, et ta peab kinni teatavatest piirangutest ja täidab teatavaid talle pandud kohustusi. Need kohustused on järgmised: + +Õigus autorsusele. Litsentsisaaja hoiab puutumatuna kõik autoriõiguse, patentide ja kaubamärkide kohta käivad märked ja kõik märked, mis viitavad litsentsile ja garantii puudumisele. Litsentsisaaja peab teose iga tema poolt levitatavale või edastatavale koopiale lisama nimetatud märgete koopiad ja litsentsi koopia. Litsentsisaaja peab tagama, et iga tuletatud teos kannab selget märget selle kohta, et teost on muudetud ja muutmise kuupäeva. + +Klausel vaba kasutamise tagamise kohta (copyleft). Kui litsentsisaaja levitab või edastab originaalteose või tuletatud teoste koopiaid, toimub see levitamine või edastamine vastavalt käesoleva litsentsi tingimustele või käesoleva litsentsi hilisema versiooni tingimustele, välja arvatud juhul, kui originaalteost levitatakse ainult vastavalt litsentsi käesolevale versioonile (näiteks märkides „ainult EUPL v.1.2“). Litsentsisaaja ei tohi (litsentsiandjaks saades) teosele või tuletatud teosele lisada ega kehtestada mingeid lisatingimusi, mis muudavad või piiravad litsentsi tingimusi. + +Ühilduvuse klausel. Kui litsentsisaaja levitab või edastab tuletatud teoseid või nende koopiaid, mis põhinevad nii teosel kui ka teisel, käesoleva litsentsiga ühilduva litsentsi alusel litsentsitud teosel, võib see levitamine või edastamine toimuda vastavalt nimetatud ühilduva litsentsi tingimustele. Käesolevas klauslis tähendab „ühilduv litsents“ käesoleva litsentsi lisas loetletud litsentse. Kui litsentsisaaja ühilduvale litsentsile vastavad kohustused on vastuolus tema kohustustega vastavalt käesolevale litsentsile, loetakse kehtivaks ühilduva litsentsi kohased kohustused. + +Lähtekoodi lisamine. Teose koopiate levitamisel või edastamisel lisab litsentsisaaja igale koopiale lähtekoodi masinloetava koopia või näitab ära hoidla, kust lähtekood on kergesti ja tasuta kättesaadav seni, kuni litsentsisaaja jätkab teose levitamist või edastamist. + +Õiguskaitse. Käesoleva litsentsiga ei anta luba kasutada litsentsiandja ärinimesid, kaubamärke, teenindusmärke või nimesid, välja arvatud juhul, kui see on vajalik mõistlikuks ja tavapäraseks kasutamiseks teose päritolu kirjeldamisel ja autoriõiguse märke sisu reprodutseerimisel. + +6.Autorsuse ahel +Esialgne litsentsiandja tagab, et käesoleva litsentsiga antav autoriõigus originaalteosele kuulub talle või on talle litsentsitud ja et tal on õigus seda litsentsiga edasi anda. Iga edasiarendaja tagab, et autoriõigus tema poolt teosele tehtavatele muudatustele kuulub talle või on talle litsentsitud ja et tal on õigus litsentsi anda. Iga kord, kui Te võtate vastu litsentsi, annavad esialgne litsentsiandja ja hilisemad edasiarendajad Teile litsentsi nende osaluse kasutamiseks teoses vastavalt käesoleva litsentsi tingimustele. + +7.Garantii puudumine +Teos on veel pooleli ja arvukad edasiarendajad parendavad seda järjepidevalt. See ei ole lõpetatud teos ja võib seetõttu sisaldada defekte ja programmivigu, mis on omased seda liiki arendustegevusele. Seetõttu levitatakse teost litsentsi alusel „sellisena, nagu see on“ ilma teose suhtes kehtiva garantiita, muu hulgas garantiita kaubandusliku kvaliteedi kohta, garantiita sobivuse kohta mingi kindla eesmärgi jaoks, garantiita defektide ja vigade puudumise kohta, garantiita täpsuse kohta ja selle kohta, et ei ole rikutud muid intellektuaalse omandi õigusi peale käesoleva litsentsi artiklis 6 nimetatud autoriõiguse. Käesolev garantii puudumise klausel on litsentsi oluline osa ja teosele õiguste andmise eeltingimus. + +8.Vastutuse välistamine +Välja arvatud tahtliku õiguserikkumise või füüsilistele isikutele tekitatud otsese kahju puhul, ei vastuta litsentsiandja mitte mingil juhul litsentsi või teose kasutamise tagajärjel tekkinud mistahes otsese või kaudse, varalise või moraalse kahju eest, muu hulgas maineväärtuse langusest tekkinud kahju, tööseisakute, arvutirikke ja talitlushäirete, andmete kadumise ja ärikahju eest, isegi juhul kui litsentsiandjat on sellise kahju tekkimise võimalikkusest teavitatud. Litsentsiandja vastutab siiski vastavalt tootevastutust käsitlevatele õigusaktidele niivõrd, kuivõrd need õigusaktid on teose suhtes kohaldatavad. + +9.Lisakokkulepped +Teose levitamisel võite Te sõlmida lisakokkuleppe, milles määratakse kindlaks käesoleva litsentsiga vastavuses olevad kohustused või teenused. Kuid kui olete nõus võtma kohustusi, võite Te tegutseda ainult iseenda nimel ja vastutusel, mitte esialgse litsentsiandja või teiste edasiarendajate nimel, ja ainult juhul, kui Te nõustute vabastama edasiarendajad vastutusest, kaitsma ja hoidma neid kahju tekkimise eest vastutuse või nõuete osas, mida nende vastu võidakse esitada selle tagajärjel, et Teie pakute garantiid või võtate lisavastutuse. + +10.Litsentsiga nõustumine +Käesoleva litsentsi sätetega saab nõustuda, klõpsates ikoonile „Nõustun“ litsentsi teksti näitava akna all või väljendades nõusolekut muul sarnasel viisil vastavalt kehtivatele õigusaktidele. Sellele ikoonile klõpsates väljendate selgelt ja pöördumatult oma nõusolekut käesoleva litsentsi ja kõigi selle tingimuste suhtes. Samuti nõustute pöördumatult käesoleva litsentsi ja kõigi selle tingimustega, kui teostate Teile käesoleva litsentsi artikliga 2 antud õigusi, näiteks kasutate teost, loote tuletatud teose või levitate või edastate teost või selle koopiaid. + +11.Üldsuse teavitamine +Juhul, kui Te kasutate teose levitamiseks või edastamiseks elektroonilisi sidevahendeid (näiteks võimaldate teose allalaadimist veebisaidilt), tuleb levitamiskanalil või andmekandjal (näiteks veebisaidil) teha üldsusele kättesaadavaks vähemalt kohaldatava õiguse alusel kohustuslik teave litsentsiandja ja litsentsi kohta ning selle kohta, kuidas see on litsentsisaajale kättesaadav, litsentsilepingu sõlmimise kohta ja selle kohta, kuidas litsentsisaaja saab litsentsi säilitada ja reprodutseerida. + +12.Litsentsi lõppemine +Litsents ja sellega antud õigused lõppevad automaatselt juhul, kui litsentsisaaja rikub litsentsi tingimusi. Sellise lõppemise korral ei lõpe ühegi sellise isiku litsents, kes sai teose litsentsisaajalt vastavalt litsentsi tingimustele, juhul kui see isik täidab jätkuvalt litsentsi tingimusi. + +13.Muud sätted +Ilma et see piiraks litsentsi artikli 9 kohaldamist, sisaldab litsents kogu kokkulepet, mis osapoolte vahel seose teosega on. Kui mõni litsentsi säte on vastavalt kohaldatavatele õigusaktidele kehtetu või seda ei ole võimalik jõustada, ei mõjuta see litsentsi kui terviku kehtivust ega jõustatavust. Sellist sätet tõlgendatakse või muudetakse nii nagu vaja, et see kehtiks ja saaks tagada selle täitmise. Euroopa Komisjon võib avaldada käesoleva litsentsi muid keeleversioone või uusi versioone või lisa uuendatud versioone, kuivõrd see on vajalik ja mõistlik, vähendamata sellega litsentsiga antavate õiguste ulatust. Litsentsi uued versioonid avaldatakse kordumatu versiooninumbriga. Käesoleva litsentsi kõik keeleversioonid, mille Euroopa Komisjon on heaks kiitnud, on võrdväärsed. Osapooled võivad kasutada enda valitud keeleversiooni. + +14.Kohtualluvus +Ilma et see piiraks konkreetse osapooltevahelise kokkuleppe kohaldamist, +— kuuluvad käesoleva litsentsi tõlgendamisest tulenevad kohtuvaidlused Euroopa Liidu institutsioonide, organite, büroode või asutuste kui litsentsiandja ja mistahes litsentsisaaja vahel Euroopa Liidu Kohtu pädevusse, nagu on sätestatud Euroopa Liidu toimimise lepingu artiklis 272, +— kuuluvad käesoleva litsentsi tõlgendamisest tulenevad kohtuvaidlused muude osapoolte vahel selle pädeva kohtu ainupädevusse, kelle tööpiirkonnas asub litsentsiandja elukoht või peamine tegevuskoht. + +15.Kohaldatav õigus +Ilma et see piiraks konkreetse osapooltevahelise kokkuleppe kohaldamist, +— kohaldatakse käesoleva litsentsi suhtes selle Euroopa Liidu liikmesriigi õigust, kus paikneb litsentsiandja peakorter, elukoht või asukoht, +— kohaldatakse litsentsi suhtes Belgia õigust, kui litsentsiandja peakorter, elukoht või asukoht asub väljaspool Euroopa Liidu liikmesriike. + +Liide +Euroopa Liidu tarkvara vaba kasutuse litsentsi artiklis 5 osutatud „ühilduvad litsentsid“ on järgmised: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) muude teoste puhul peale tarkvara +— European Union Public Licence (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence – Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+). +Euroopa Komisjon võib käesolevat lisa ajakohastada loetletud litsentside hilisemate versioonidega ilma, et peaks selleks koostama EUPLi uue versiooni, eeldusel et nende litsentsidega tagatakse käesoleva litsentsi artiklis 2 sätestatud õigused ja kaitstakse hõlmatud lähtekoodi eksklusiivse omastamise eest. +Kõigi muude käesoleva liite muudatuste või täienduste jaoks on vaja koostada EUPLi uus versioon. diff --git a/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 FI.txt b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 FI.txt new file mode 100644 index 0000000..a99bc7f --- /dev/null +++ b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 FI.txt @@ -0,0 +1,95 @@ +EUROOPAN UNIONIN YLEINEN LISENSSI v. 1.2 +EUPL © Euroopan unioni 2007, 2016 +Tätä Euroopan unionin yleistä lisenssiä (”EUPL”) sovelletaan teokseen (sellaisina kuin se määritellään jäljempänä), joka toimitetaan tämän lisenssin ehdoilla. Teoksen kaikki muu kuin tämän lisenssin nojalla sallittu käyttö on kielletty (siltä osin kuin tällainen käyttö on suojattu teoksen tekijänoikeuden haltijan oikeuksilla). Teos toimitetaan tämän lisenssin ehdoilla silloin kun lisenssinantaja (sellaisena kuin se määritellään jäljempänä) on asettanut seuraavan ilmoituksen välittömästi teoksen tekijänoikeusilmoituksen perään: + Lisensoitu EUPL:n nojalla +tai ilmaissut muilla keinoin suostumuksensa EUPL:n mukaiseen lisenssin myöntämiseen. + +1.Määritelmät +Tässä lisenssissä seuraavilla termeillä on seuraavat merkitykset: +— ”Lisenssi”:tämä lisenssi. +— ”Alkuperäisteos”:lisenssinantajan tämän lisenssin mukaisesti levittämä tai luovuttama teos tai ohjelmisto, joka on saatavana lähdekoodina sekä mahdollisesti myös suoritettavana koodina. +— ”Jälkiperäisteokset”:teokset tai ohjelmistot, joita lisenssinsaaja voi luoda alkuperäisteoksen tai sen muunnelmien pohjalta. Tässä lisenssissä ei määritellä, minkä laajuinen muuntelu tai riippuvuus alkuperäisteoksesta riittää luokittelemaan teoksen jälkiperäisteokseksi; tämä laajuus määritetään 15 kohdassa mainitussa maassa sovellettavassa tekijänoikeuslaissa. +— ”Teos”:alkuperäisteos tai sen jälkiperäisteokset. +— ”Lähdekoodi”:teos ihmiselle luettavassa muodossa, jossa sitä on helpointa tutkia ja muunnella. +— ”Suoritettava koodi”:mikä tahansa koodi, yleensä käännettynä, joka on tarkoitettu tietokoneen tulkittavaksi ohjelmana. +— ”Lisenssinantaja”:luonnollinen henkilö tai oikeushenkilö, joka levittää tai luovuttaa lisenssin alaista teosta. +— ”Muu(t) tekijä(t)”:luonnollinen henkilö tai oikeushenkilö, joka muuntelee lisenssin alaista teosta tai muutoin myötävaikuttaa jälkiperäisteoksen luomiseen. +— ”Lisenssinsaaja” tai ”te”:luonnollinen henkilö tai oikeushenkilö, joka jollain tavoin käyttää teosta lisenssin ehdoilla. +— ”Levittäminen” tai ”luovuttaminen”:kaikki toimet, joilla teoskappaleita myydään, annetaan, lainataan, vuokrataan, levitetään, luovutetaan, lähetetään tai muutoin asetetaan luonnollisten ja oikeushenkilöiden saataville tai joilla tarjotaan pääsyä teoksen olennaisiin toimintoihin verkon kautta tai sen ulkopuolella. + +2.Tällä lisenssillä myönnettävien oikeuksien laajuus +Lisenssinantaja myöntää teille maailmanlaajuisen, rojaltimaksuttoman, yksinoikeudettoman, alilisensoitavan lisenssin seuraaviin toimiin alkuperäisteokseen kohdistuvien tekijänoikeuksien ajaksi: +— teoksen käyttö kaikissa olosuhteissa ja käyttötarkoituksissa, +— teoksen toisinto, +— teoksen muuntelu ja teokseen perustuvien jälkiperäisteosten tekeminen, +— teoksen luovuttaminen yleisölle, mukaan lukien oikeus asettaa teos tai teoskappaleita yleisön saataville tai näytteille sekä mahdollisesti suorittaa teos julkisesti, +— teoksen tai teoskappaleiden levittäminen, +— teoksen tai teoskappaleiden lainaaminen ja vuokraaminen, +— teoksen tai teoskappaleiden oikeuksien alilisensointi. +Näitä oikeuksia voidaan harjoittaa millä tahansa välineellä, alustalla tai muodolla, riippumatta siitä onko se tiedossa nyt tai keksitäänkö se myöhemmin, kunhan sovellettavaa lakia noudatetaan. Maissa, joissa sovelletaan moraalisia oikeuksia, lisenssinantaja luopuu oikeudestaan harjoittaa moraalista oikeuttaan lain sallimassa laajuudessa, jotta edellä lueteltujen taloudellisten oikeuksien lisensointi olisi tehokasta. Lisenssinantaja myöntää lisenssinsaajalle rojaltimaksuttomat, yksinoikeudettomat käyttöoikeudet kaikkiin lisenssinantajan hallussa pitämiin patentteihin siinä määrin kuin on tarpeen tällä lisenssillä teokseen myönnettyjen oikeuksien käyttämiseksi. + +3.Lähdekoodin luovuttaminen +Lisenssinantaja voi toimittaa teoksen joko lähdekoodina tai suoritettavana koodina. Jos teos toimitetaan suoritettavana koodina, lisenssinantaja toimittaa lisäksi koneella luettavan kopion teoksen lähdekoodista lisenssinantajan levittämän kunkin teoskappaleen yhteydessä tai ilmoittaa teokseen liitetyn tekijänoikeusilmoituksen perään lisätyssä ilmoituksessa paikan, josta lähdekoodi on helposti ja vapaasti saatavissa niin pitkään kuin lisenssinantaja jatkaa teoksen levittämistä tai luovuttamista. + +4.Tekijänoikeuden rajoitukset +Tässä lisenssissä ei ole mitään sellaista, jonka tarkoitus on estää lisenssinsaajaa hyötymästä oikeudenomistajien teokseen kohdistuvien yksinoikeuksien poikkeuksesta tai rajoituksesta, näiden oikeuksien päättymisestä tai muista niihin sovellettavista rajoituksista. + +5.Lisenssinsaajan velvoitteet +Edellä mainittujen oikeuksien myöntäminen lisenssinsaajalle on sidottu tiettyihin rajoituksiin ja velvoitteisiin. Nämä velvoitteet ovat seuraavat: + +Isyysoikeus: Lisenssinsaajan on pidettävä koskemattomina kaikki tekijänoikeus-, patentti- tai tavaramerkki-ilmoitukset sekä kaikki ilmoitukset, jotka viittaavat lisenssiin ja takuunrajoituksiin. Lisenssinsaajan on sisällytettävä jäljennös tällaisista ilmoituksista ja lisenssistä jokaiseen levittämäänsä tai luovuttamaansa teoskappaleeseen. Lisenssinsaajan on huolehdittava siitä, että kaikissa jälkiperäisteoksissa on näkyvä ilmoitus siitä, että teosta on muunneltu. Ilmoituksen on sisällettävä myös muuntelun päiväys. + +Copyleft-lauseke: Jos lisenssinsaaja levittää tai luovuttaa alkuperäisteosten tai jälkiperäisteosten teoskappaleita, tämä levittäminen tai luovuttaminen tapahtuu tämän lisenssin tai sen myöhemmän version ehdoilla, paitsi jos alkuperäisteosta levitetään nimenomaisesti lisenssin tämän version ehdoilla – esimerkiksi ilmoittamalla ”ainoastaan EUPL v. 1.2”. Lisenssinsaaja (josta tulee lisenssinantaja) ei voi tarjota tai asettaa teokselle tai jälkiperäisteokselle mitään lisäehtoja tai -edellytyksiä, jotka muuttavat tai rajoittavat lisenssin ehtoja. + +Yhteensopivuuslauseke: Jos lisenssinsaaja levittää tai luovuttaa jälkiperäisteoksia tai sen teoskappaleita, jotka perustuvat sekä teokseen että muuhun teokseen, joka on lisensoitu jollakin yhteensopivalla lisenssillä, tämä levittäminen tai luovuttaminen voi tapahtua tämän yhteensopivan lisenssin ehdoilla. Tämän lausekkeen soveltamiseksi ”yhteensopivalla lisenssillä” tarkoitetaan tämän lisenssin lisäyksessä lueteltuja lisenssejä. Jos lisenssinsaajalla on yhteensopivan lisenssin mukaisia velvoitteita, jotka ovat ristiriidassa hänen tämän lisenssin mukaisten velvoitteidensa kanssa, sovelletaan yhteensopivan lisenssin velvoitteita. + +Lähdekoodin toimittaminen: Levittäessään tai luovuttaessaan teoksesta teoskappaleita lisenssinsaaja toimittaa koneella luettavan kopion lähdekoodista tai ilmoittaa paikan, josta lähdekoodi on helposti ja vapaasti saatavissa niin pitkään kuin lisenssinsaaja jatkaa teoksen levittämistä tai luovuttamista. + +Oikeussuoja: Tämä lisenssi ei anna lupaa käyttää kauppanimiä, tavaramerkkejä, palvelumerkkejä tai lisenssinantajan nimiä paitsi siltä osin kuin niiden kohtuullinen ja tavanmukainen käyttö edellyttää teoksen alkuperän kuvailemisessa ja tekijänoikeusilmoituksen sisällön toisintamisessa. + +6.Tekijyysketju +Alkuperäinen lisenssinantaja takaa, että hän omistaa tällä lisenssillä myönnettävän tekijänoikeuden alkuperäisteokseen tai se on lisensoitu hänelle ja että hänellä on oikeus ja valtuudet lisenssin myöntämiseen. Jokainen muu tekijä takaa, että hän omistaa teokseen tekemiensä muunnelmien tekijänoikeuden tai se on lisensoitu hänelle ja että hänellä on oikeus ja valtuudet lisenssin myöntämiseen. Aina kun hyväksytte lisenssin, alkuperäinen lisenssinantaja ja sen jälkeiset muut tekijät antavat teille lisenssin omaan panokseensa teoksessa tämän lisenssin ehdoilla. + +7.Takuunrajoitus +Teos on tekeillä oleva teos, jota lukuisat muut tekijät parantelevat jatkuvasti. Se ei ole viimeistelty teos ja saattaa sen vuoksi sisältää tämänkaltaiselle kehitykselle tunnusomaisia toimintavirheitä (”bugeja”). Tästä syystä teos toimitetaan lisenssin nojalla ”sellaisena kuin se on” ilman minkäänlaisia teokseen liittyviä takuita, mukaan lukien takuut soveltuvuudesta kaupankäynnin kohteeksi, sopivuudesta johonkin tiettyyn tarkoitukseen, virheettömyydestä, oikeellisuudesta ja muiden teollis- ja tekijänoikeuksien kuin tämän lisenssin 6 kohdassa tarkoitettujen tekijänoikeuksien loukkaamattomuudesta. Tämä takuunrajoitus on olennainen osa lisenssiä ja ehtona teokseen kohdistuvien oikeuksien myöntämiselle. + +8.Vastuunrajoitus +Lukuun ottamatta tapauksia, joissa on kyse tahallisesta teosta tai luonnollisille henkilöille välittömästi aiheutetusta vahingosta, lisenssinantaja ei ole missään tapauksessa vastuussa minkäänlaisesta välittömästä tai välillisestä, materiaalisesta tai moraalisesta vahingosta, joka johtuu lisenssistä tai teoksen käytöstä, mukaan lukien vahingot liikearvon menettämisestä, työnseisauksesta, tietokoneen viasta tai toimintahäiriöstä, tietojen menettämisestä tai liiketaloudellisesta vahingosta, vaikka lisenssinantajalle olisi ilmoitettu tällaisen vahingon mahdollisuudesta. Lisenssinantaja on kuitenkin tuotevastuulakien alaisessa vastuussa siltä osin kuin näitä lakeja sovelletaan teokseen. + +9.Lisäsopimukset +Teosta levittäessänne voitte halutessanne tehdä lisäsopimuksen, jolla määritellään tämän lisenssin mukaisesti velvoitteet tai palvelut. Jos kuitenkin hyväksytte velvoitteita, voitte toimia ainoastaan omasta puolestanne ja omalla vastuullanne ettekä alkuperäisen lisenssinantajan tai kenenkään muun tekijän puolesta, ja ainoastaan jos suostutte vapauttamaan kunkin muun tekijän vastuusta, puolustamaan häntä ja pitäytymään aiheuttamasta hänelle haittaa, jos se, että olette hyväksyneet takuun tai lisävastuun, aiheuttaa tällaiselle muulle tekijälle vastuita tai vaatimuksia. + +10.Lisenssin hyväksyminen +Voitte hyväksyä tämän lisenssin määräykset napsauttamalla ”Hyväksyn”-kuvaketta, joka on tämän lisenssin tekstin esittävän ikkunan alareunassa, tai vahvistamalla suostumuksenne muulla vastaavalla tavalla sovellettavan lain mukaisesti. Napsauttamalla kuvaketta ilmoitatte hyväksyvänne yksiselitteisesti ja peruuttamattomasti tämän lisenssin ja kaikki sen ehdot ja edellytykset. Samoin ilmoitatte hyväksyvänne peruuttamattomasti tämän lisenssin ja kaikki sen ehdot ja edellytykset harjoittamalla mitä tahansa teille tämän lisenssin 2 kohdalla myönnettyjä oikeuksia, kuten teoksen käyttö, jälkiperäisteoksen luominen tai teoksen tai sen teoskappaleiden levittäminen tai luovuttaminen. + +11.Tiedottaminen yleisölle +Teoksen levittämisessä tai luovuttamisessa sähköisen viestinnän keinoin (esimerkiksi tarjoamalla teoksen ladattavaksi etäpisteestä käsin) jakelukanavan tai viestimen (esimerkiksi verkkosivun) on annettava yleisölle vähintään sovellettavan lain edellyttämät tiedot lisenssinantajasta, lisenssistä ja tavoista, joilla lisenssinsaaja voi saada, solmia, tallentaa ja toisintaa sen. + +12.Lisenssin päättyminen +Lisenssi ja sen nojalla myönnetyt oikeudet päättyvät automaattisesti lisenssinsaajan rikkoessa mitä tahansa tämän lisenssin ehtoja. Tällainen päättyminen ei päätä lisenssejä muilta henkilöiltä, jotka ovat saaneet teoksen lisenssinsaajalta tämän lisenssin nojalla, jos nämä henkilöt jatkavat lisenssin ehtojen täydellistä noudattamista. + +13.Muuta +Rajoittamatta 9 kohdan soveltamista lisenssi edustaa kaiken kattavaa sopimusta sopimuspuolten välillä teoksen osalta. Jos jokin lisenssin määräys on sovellettavan lain osalta pätemätön tai täytäntöönpanokelvoton, tämä ei vaikuta lisenssin pätevyyteen tai täytäntöönpanokelpoisuuteen kokonaisuutena. Tällainen määräys tulkitaan tai muotoillaan uudelleen tarpeen mukaan siten, että siitä tulee pätevä ja täytäntöönpanokelpoinen. Euroopan komissio voi julkaista tästä lisenssistä muita kieliversioita tai uusia versioita tai lisäyksen päivitettyjä versioita, sikäli kuin tämä on tarpeen ja kohtuullista, rajoittamatta tällä lisenssillä myönnettävien oikeuksien laajuutta. Lisenssin uudet versiot julkaistaan ainutkertaisella versionumerolla. Kaikki Euroopan komission hyväksymät kieliversiot tästä lisenssistä ovat samanarvoisia. Sopimuspuolet voivat käyttää valitsemaansa kieliversiota. + +14.Toimivalta +Rajoittamatta sopimuspuolten välistä erityistä sopimusta +— Euroopan unionin tuomioistuimella on toimivalta ratkaista kaikki tämän lisenssin tulkinnasta aiheutuvat riita-asiat Euroopan unionin toimielinten, elinten, toimistojen tai virastojen, lisenssinantajan ominaisuudessa, ja kenen tahansa lisenssinsaajan välillä Euroopan unionin toiminnasta tehdyn sopimuksen 272 artiklassa määrätyllä tavalla, +— kaikissa tämän lisenssin tulkinnasta aiheutuvissa riita-asioissa, joissa asianosaisena on muu osapuoli, yksinomainen toimivalta on toimivaltaisella tuomioistuimella siinä maassa, jossa lisenssinantaja asuu tai harjoittaa pääasiallista liiketoimintaansa. + +15.Sovellettava laki +Rajoittamatta sopimuspuolten välistä erityistä sopimusta — tähän lisenssiin sovelletaan sen Euroopan unionin jäsenvaltion lakia, jossa on lisenssinantajan kotipaikka tai jossa lisenssinantaja asuu tai hänellä on sääntömääräinen toimipaikka, — tähän lisenssiin sovelletaan Belgian lakia, jos lisenssinantajalla ei ole kotipaikkaa tai lisenssinantaja ei asu tai hänellä ei ole sääntömääräistä toimipaikkaa Euroopan unionin jäsenvaltiossa. + +Lisäys +EUPL:n 5 kohdan mukaisia ”yhteensopivia lisenssejä” ovat seuraavat: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) muiden teosten kuin ohjelmiston osalta +— European Union Public Licence (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence – Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+). +Euroopan komissio voi päivittää tätä lisäystä edellä mainittujen lisenssien myöhempiin versioihin laatimatta uutta versiota EUPL:stä, kunhan niillä tarjotaan tämän lisenssin 2 kohdassa myönnetyt oikeudet ja suojataan niiden piiriin kuuluva lähdekoodi yksinomaiseen oikeuteen perustuvalta käytöltä. +Kaikki muut tämän lisäyksen muutokset tai siihen tehtävät lisäykset edellyttävät uuden EUPL-version laatimista. 19.5.2017 L 128/64 Euroopan unionin virallinen lehti FI diff --git a/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 FR.txt b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 FR.txt new file mode 100644 index 0000000..d54e195 --- /dev/null +++ b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 FR.txt @@ -0,0 +1,97 @@ +LICENCE PUBLIQUE DE L'UNION EUROPÉENNE v. 1.2 +EUPL © Union européenne 2007, 2016 + +La présente licence publique de l'Union européenne («EUPL») s'applique à toute œuvre (telle que définie ci-dessous) fournie aux conditions prévues par la présente licence. Toute utilisation de l'œuvre autre que ce qu'autorise la présente licence est interdite (dans la mesure où pareille utilisation est couverte par un droit du titulaire des droits d'auteur sur l'œuvre). L'œuvre est fournie aux conditions prévues par la présente licence quand le donneur de licence (tel que défini ci-dessous) a placé la mention suivante immédiatement après la déclaration relative au droit d'auteur sur l'œuvre: + Sous licence EUPL +ou a exprimé de toute autre manière sa volonté de fournir l'œuvre sous licence EUPL. + +1.Définitions +Dans la présente licence, on entend par: +— «licence», la présente licence, +— «œuvre originale», l'œuvre ou le logiciel distribué ou communiqué par le donneur de licence en vertu de la présente licence, sous forme de code source ou de code objet, selon le cas, +— «œuvres dérivées», les œuvres ou logiciels qui pourraient être créés par le licencié sur la base de l'œuvre originale ou des modifications qui y auraient été appliquées. La présente licence ne définit pas le degré de modification ou de dépendance requis par rapport à l'œuvre originale pour qu'une œuvre soit qualifiée d'œuvre dérivée; cette question est réglée par la loi applicable en matière de droit d'auteur dans le pays visé à l'article 15, +— «œuvre», l'œuvre originale ou ses œuvres dérivées, +— «code source», la forme de l'œuvre, lisible par l'homme, la plus appropriée pour que des personnes puissent l'examiner et la modifier, +— «code objet», l'œuvre codée, généralement après compilation, destinée à être exécutée en tant que programme par un ordinateur, — «donneur de licence», la personne physique ou morale qui distribue ou communique l'œuvre sous licence, +— «contributeur», toute personne physique ou morale qui modifie l'œuvre sous licence, ou contribue de toute autre manière à en faire une œuvre dérivée, +— «licencié» ou «vous», toute personne physique ou morale qui utilise l'œuvre conformément à la licence, +— «distribution» ou «communication», tout acte de vente, don, prêt, location, distribution, communication, transmission ou mise à disposition, en ligne ou hors ligne, de copies de l'œuvre, et tout acte donnant accès à ses fonctions essentielles à toute autre personne physique ou morale. + +2.Portée des droits accordés par la licence +Par la présente, le donneur de licence vous concède, pour la durée de la protection de son droit d'auteur sur l'œuvre originale, une licence mondiale, libre de redevances, non exclusive et pouvant faire l'objet de sous-licences, en vertu de laquelle vous pouvez: +— utiliser l'œuvre en toute circonstance et pour tout usage, +— reproduire l'œuvre, +— modifier l'œuvre et créer des œuvres dérivées sur la base de l'œuvre, +— communiquer l'œuvre au public, ce qui inclut le droit de mettre à disposition du public ou de lui présenter l'œuvre ou des copies de l'œuvre et d'en effectuer des représentations publiques, le cas échéant, +— distribuer l'œuvre ou des copies de celle-ci, +— prêter et louer l'œuvre ou des copies de celles-ci, +— accorder en sous-licence des droits sur l'œuvre ou sur des copies de celle-ci. +Ces droits peuvent être exercés sur tout support et format, connu ou encore à inventer, dans la mesure où le droit applicable le permet. Dans les pays où des droits moraux s'appliquent, le donneur de licence renonce à son droit d'exercer son droit moral dans la mesure permise par la loi afin que la licence sur les droits patrimoniaux susmentionnés produise ses effets. Le donneur de licence vous concède un droit d'usage libre de redevances et non exclusif sur tout brevet qu'il détient, dans la mesure nécessaire à l'exercice des droits qui vous sont concédés sur l'œuvre sous licence. + +3.Communication du code source +Le donneur de licence fournit l'œuvre sous forme de code source ou de code objet. Si l'œuvre est fournie sous forme de code objet, le donneur de licence accompagne chacune des copies de l'œuvre qu'il distribue d'une copie lisible par machine du code source de l'œuvre ou indique, dans un avis qui suit la déclaration relative au droit d'auteur jointe à l'œuvre, l'endroit où le code source est aisément et gratuitement accessible aussi longtemps que le donneur de licence continue à distribuer ou communiquer l'œuvre. + +4.Limitations du droit d'auteur +Rien dans la présente licence n'a pour but de priver le licencié des avantages résultant de toute exception ou limitation aux droits exclusifs des titulaires de droits sur l'œuvre, de l'épuisement de ces droits ou de toute autre limitation qui s'y applique. + +5.Obligations du licencié +La concession des droits susmentionnés est soumise à des restrictions et à des obligations pour le licencié. Ces obligations sont les suivantes: + +Droit d'attribution: le licencié laisse intactes toutes les déclarations concernant le droit d'auteur, le brevet ou les marques et toutes les déclarations concernant la licence et l'exclusion de garantie. Le licencié assortit chaque copie de l'œuvre qu'il distribue ou communique d'une copie de ces déclarations et d'une copie de la licence. Le licencié veille à ce que toute œuvre dérivée soit assortie d'un avis bien visible indiquant que l'œuvre a été modifiée et mentionnant la date de la modification. + +Clause copyleft: si le licencié distribue ou communique des copies d'œuvres originales ou d'œuvres dérivées, cette distribution ou cette communication est effectuée dans les conditions prévues par la présente licence ou une version ultérieure de cette licence, sauf si l'œuvre originale est expressément distribuée en vertu de la présente version de la licence uniquement, par exemple au moyen de la mention «EUPL v. 1.2 seulement». Le licencié (qui devient donneur de licence) ne peut pas, en ce qui concerne l'œuvre ou les œuvres dérivées, offrir ou imposer des conditions supplémentaires qui restreignent ou modifient les conditions de la licence. + +Clause de compatibilité: si le licencié distribue ou communique des œuvres dérivées ou des copies de telles œuvres basées à la fois sur l'œuvre et sur une autre œuvre concédée sous une licence compatible, la distribution ou la communication peut être faite aux conditions de cette licence compatible. Aux fins de la présente clause, une «licence compatible» est l'une des licences énumérées dans l'appendice de la présente licence. Dans le cas où les obligations du licencié au titre de la licence compatible entrent en conflit avec les obligations du licencié au titre de la présente licence, les premières prévalent. + +Fourniture du code source: lorsqu'il distribue ou communique des copies de l'œuvre, le licencié fournit une copie lisible par machine du code source ou indique l'endroit où ce code source restera aisément et gratuitement accessible aussi longtemps que le donneur de licence continuera à distribuer ou communiquer l'œuvre. + +Protection des droits: la présente licence ne donne pas le droit d'utiliser les noms commerciaux, les marques commerciales, les marques de service ou les noms du donneur de licence, sauf dans la mesure nécessaire, conformément à une utilisation raisonnable et aux pratiques habituelles, pour décrire l'origine de l'œuvre et reproduire la déclaration concernant le droit d'auteur. + +6.Chaîne d'auteurs +Le donneur de licence initial garantit que les droits d'auteur sur l'œuvre originale concédés par la présente licence lui appartiennent ou lui ont été donnés sous licence, et qu'il a le pouvoir et la capacité de concéder la licence. Tout contributeur garantit que les droits d'auteur sur les modifications qu'il apporte à l'œuvre lui appartiennent ou lui ont été donnés sous licence, et qu'il a le pouvoir et la capacité de concéder la licence. Chaque fois que vous acceptez la licence, le donneur de licence initial et les contributeurs successifs vous concèdent une licence sur leurs contributions à l'œuvre selon les conditions de la présente licence. + +7.Exclusion de garantie +L'œuvre est un travail en cours, amélioré de manière continue par de nombreux contributeurs. Elle constitue un travail inachevé et peut dès lors contenir des défauts ou bogues inhérents à ce type de développement. Pour cette raison, l'œuvre est fournie sous licence telle quelle, sans aucune garantie d'aucune sorte la concernant, y compris, sans que cette liste soit exhaustive, eu égard à sa qualité marchande, son aptitude à un usage particulier, l'absence de défauts ou d'erreurs, l'exactitude ou la non-violation de droits de propriété intellectuelle autres que le droit d'auteur comme prévu à l'article 6 de la présente licence. Cette exclusion de garantie est une partie essentielle de la licence et une condition de la concession de droits sur l'œuvre. + +8.Exclusion de responsabilité +Sauf dans les cas de faute intentionnelle ou de dommages directement causés à des personnes physiques, le donneur de licence n'est en aucun cas responsable des dommages, quelle qu'en soit la nature, directs ou indirects, matériels ou moraux, résultant de la licence ou de l'utilisation de l'œuvre, y compris, sans que cette liste soit exhaustive, des dommages causés par les atteintes à la réputation, les interruptions de travail, les défaillances ou le mauvais fonctionnement de matériel informatique, les pertes de données ou tout autre dommage économique, même si le donneur de licence a été informé de la possibilité de tels dommages. Cependant, le donneur de licence est responsable en vertu des dispositions législatives et réglementaires relatives à la responsabilité du fait des produits, dans la mesure où celles-ci sont applicables à l'œuvre. + +9.Accords additionnels +Lorsque vous distribuez l'œuvre, vous pouvez choisir de conclure un accord additionnel définissant des obligations ou des services compatibles avec la présente licence. Cependant, si vous acceptez des obligations, vous ne pouvez agir qu'en votre nom et sous votre seule responsabilité, et non au nom du donneur de licence initial ou de tout autre contributeur, et seulement si vous acceptez d'indemniser, de défendre et de mettre hors de cause tous les contributeurs s'ils encourent une responsabilité quelconque ou si des réclamations sont formulées à leur encontre du fait que vous avez accepté des garanties ou des responsabilités additionnelles. + +10.Acceptation de la licence +Vous pouvez exprimer votre accord sur le contenu de la présente licence en cliquant sur l'icône «J'accepte» placée au bas d'une fenêtre faisant apparaître le texte de la présente licence, ou par toute autre manifestation de consentement similaire, conformément à la loi applicable. Le fait de cliquer sur cette icône indique votre acceptation claire et irrévocable de la présente licence et de toutes ses conditions. De même, vous acceptez irrévocablement la présente licence et toutes ses conditions dès lors que vous exercez un des droits qui vous sont concédés par l'article 2 de la présente licence, tels que l'utilisation de l'œuvre, la création d'une œuvre dérivée ou la distribution ou la communication de l'œuvre ou de copies de l'œuvre. + +11.Information du public +En cas de distribution ou de communication électronique de l'œuvre (par exemple en permettant son téléchargement à distance), le canal de distribution ou le support (par exemple un site web) doit au minimum fournir au public les informations requises par le droit applicable en ce qui concerne le donneur de licence et la licence ainsi que la manière dont le licencié peut accéder à celle-ci, la conclure, la stocker et la reproduire. + +12.Fin de la licence +La licence et les droits qu'elle concède prennent automatiquement fin dès que le licencié viole l'une de ses conditions. Un tel événement ne met pas fin aux licences des personnes ayant reçu l'œuvre sous licence de la part du licencié, pour autant que ces personnes respectent pleinement la licence. + +13.Divers +Sous réserve de l'article 9, la licence représente l'entièreté de l'accord entre les parties quant à l'œuvre. Le fait qu'une clause quelconque de la licence soit invalide ou inapplicable en vertu du droit applicable n'affecte pas la validité ou l'applicabilité de la licence dans son ensemble. Une telle clause sera interprétée ou modifiée dans la mesure nécessaire pour la rendre valide ou applicable. La Commission européenne peut publier d'autres versions linguistiques ou de nouvelles versions de la présente licence ou des versions actualisées de son appendice, dans la mesure de ce qui est nécessaire et raisonnable, sans réduire la portée des droits accordés par la licence. Les nouvelles versions de la licence seront publiées avec un numéro de version unique. Toutes les versions linguistiques de la présente licence, approuvées par la Commission européenne, ont la même valeur. Les parties peuvent se prévaloir de la version linguistique de leur choix. + +14.Juridiction compétente +Sans préjudice d'accords spécifiques entre les parties, +— tout litige résultant de l'interprétation de la présente licence survenant entre des institutions, organes, bureaux ou agences de l'Union européenne en tant que donneurs de licence et un licencié relève de la juridiction de la Cour de justice de l'Union européenne, conformément à l'article 272 du traité sur le fonctionnement de l'Union européenne, +— tout litige survenant entre d'autres parties et résultant de l'interprétation de la présente licence relève de la compétence exclusive de la juridiction compétente du lieu où le donneur de licence réside ou exerce son activité principale. + +15.Droit applicable +Sans préjudice d'accords spécifiques entre les parties, +— la présente licence est régie par le droit de l'État membre de l'Union européenne où le donneur de licence réside ou a son siège social ou statutaire, +— la présente licence est régie par le droit belge si le donneur de licence ne réside pas et n'a pas son siège social ou statutaire dans un État membre de l'Union européenne. + +Appendice +Aux fins de l'article 5 de l'EUPL, les licences compatibles sont les suivantes: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public licence (MPL) v. 2 +— GNU Lesser General Public licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) pour les œuvres autres que logicielles +— Licence publique de l'Union européenne (EUPL) v. 1.1, v. 1.2 +— Licence libre du Québec — Réciprocité (LiLiQ-R) ou Réciprocité forte (LiLiQ-R+) +La Commission européenne pourra actualiser le présent appendice afin d'y inclure des versions ultérieures des licences ci-dessus sans produire de nouvelle version de l'EUPL, dès lors que ces versions prévoient la concession des droits visés à l'article 2 de la présente licence et empêchent l'appropriation exclusive du code source couvert. +Tout autre changement ou ajout au présent appendice requiert la production d'une nouvelle version de l'EUPL. \ No newline at end of file diff --git a/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 HR.txt b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 HR.txt new file mode 100644 index 0000000..e8fd439 --- /dev/null +++ b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 HR.txt @@ -0,0 +1,97 @@ +JAVNA LICENCIJA EUROPSKE UNIJE v. 1.2. +EUPL © Europska unija 2007., 2016. +Javna licencija Europske unije („EUPL”) odnosi se na djela (kako su definirana u nastavku) koja se stavljaju na raspolaganje u skladu s uvjetima ove licencije. Zabranjena je svaka uporaba djela koja nije odobrena ovom licencijom (ako je ta uporaba obuhvaćena pravom koje ima nositelj autorskog prava za to djelo). Djelo se stavlja na raspolaganje u skladu s uvjetima ove licencije ako je davatelj licencije (kako je definiran u nastavku) nakon obavijesti o autorskim pravima za to djelo stavio sljedeću obavijest: + Licencirano u skladu s uvjetima EUPL-a +ili je na bilo koji drugi način izrazio spremnost davanja licence u skladu s uvjetima EUPL-a. + +1.Definicije +U ovoj licenciji sljedeći pojmovi imaju sljedeća značenja: +— „licencija”:ova licencija, +— „originalno djelo”:djelo ili softver koje davatelj licencije distribuira ili stavlja na raspolaganje u skladu s ovom licencijom, dostupno u obliku izvornog ili izvršnog koda, ovisno o slučaju, +— „izvedena djela”:djela ili softver koje bi davatelj licencije mogao proizvesti na temelju originalnog djela ili njegovih izmjena. Ovom licencijom nije utvrđena dopuštena mjera izmjene originalnog djela i ovisnost o njemu potrebna kako bi se određeno djelo smatralo izvedenim djelom. Ta je mjera utvrđena zakonom o autorskom pravu primjenjivim u zemlji iz članka 15., +— „djelo”:originalno djelo ili njegova izvedena djela, +— „izvorni kôd”:djelo u formatu koji je čitljiv ljudima te najpogodniji za proučavanje i izmjenu, +— „izvršni kôd”:svaki kôd, koji je u načelu sastavljen, namijenjen da ga računalo izvršava kao program, +— „davatelj licencije”:fizička ili pravna osoba koja distribuira ili stavlja na raspolaganje djelo u skladu s uvjetima licencije, +— „sudionik”:svaka fizička ili pravna osoba koja je izmijenila djelo u skladu s uvjetima licencije ili koja je drukčije pridonijela izradi izvedenog djela, +— „nositelj licencije” ili „vi/vas/vam”:svaka fizička ili pravna osoba koja se koristi djelom u skladu s uvjetima licencije, +— „distribucija ili stavljanje na raspolaganje”:svaki čin prodaje kopija djela, njihovo davanje, posudba, iznajmljivanje, distribucija, objava, prijenos ili stavljanje na raspolaganje na drukčiji način, na mreži ili izvan nje, drugoj fizičkoj ili pravnoj osobi ili omogućivanja pristupa osnovnim funkcijama djela. + +2.Opseg prava dodijeljenih licencijom +Davatelj odobrenja daje vam sljedeću besplatnu, neisključivu licenciju, s pravom podlicenciranja, koja vrijedi u cijelom svijetu, na temelju koje tijekom trajanja zaštite autorskog prava dodijeljenog za originalno djelo možete: +— koristiti se djelom u svim okolnostima i za sve namjene, +— reproducirati djelo, +— izmijeniti djelo i proizvesti izvedena djela na temelju njega, +— objaviti djelo, uključujući pravo stavljanja na raspolaganje ili prikaza djela ili njegovih kopija javnosti te javne izvedbe djela, ovisno o slučaju, +— distribuirati djelo ili njegove kopije, +— posuđivati i iznajmljivati djelo ili njegove kopije, +— podlicencirati prava na djelo ili njegove kopije. +Ta se prava mogu ostvarivati na bilo kojem mediju, podršci ili formatu, neovisno o tome jesu li već poznati ili će se tek izumjeti, ako je to dopušteno zakonom. U zemljama u kojima se primjenjuju moralna prava davatelj licencije odriče se tih prava, ako je to dopušteno zakonom, radi bolje učinkovitosti licencije u pogledu prethodno navedenih ekonomskih prava. Davatelj licencije nositelju licencije daje besplatna, neisključiva prava na uporabu svih svojih patenata ako je to potrebno za ostvarivanje prava dodijeljenih za djelo u skladu s ovom licencijom. + +3.Stavljanje izvornog koda na raspolaganje +Davatelj licencije djelo može staviti na raspolaganje u obliku izvornog ili izvršnog koda. Ako se djelo stavi na raspolaganje kao izvršni kôd, davatelj licencije dužan je uz svaku kopiju djela koju distribuira dodatno dostaviti strojno čitljivu inačicu izvornog koda djela ili navesti – u obavijesti koja slijedi nakon obavijesti o autorskom pravu priložene djelu – repozitorij s pomoću kojeg se može jednostavno i besplatno pristupati izvornom kodu sve dok davatelj licencije distribuira ili stavljanja djelo na raspolaganje. + +4.Ograničenja autorskog prava +Svrha ove licencije nije uskratiti nositelju licencije mogućnost ostvarivanja koristi od iznimaka ili od ograničenja u pogledu isključivih prava koja imaju nositelji prava za određeno djelo, iscrpljenja prava ili iskorištavanja drugih primjenjivih ograničenja. + +5.Obveze povezane s licencijom +Dodjela prethodno navedenih prava podliježe određenim ograničenjima i obvezama koje se nameću licencijom. Riječ je o sljedećim obvezama: + +Pravo pripisivanja: nositelj licencije ne smije mijenjati ni jednu obavijest o autorskom pravu, patentu ili zaštićenim žigovima ni bilo koju obavijest koja se odnosi na licenciju i ograničenje odgovornosti u pogledu jamstava. Nositelj licencije uz svaku kopiju djela koju distribuira ili stavi na raspolaganje mora dostaviti i primjerak tih obavijesti te primjerak licencije. Nositelj licencije mora osigurati da svako izvedeno djelo sadržava jasne obavijesti koje sadržavaju informaciju da je djelo izmijenjeno i datum izmjene. + +Klauzula o oslobođenju od autorskog prava (engl. Copyleft): ako nositelj licencije distribuira ili stavlja na raspolaganje kopije izvornih ili izvedenih djela, te se aktivnosti moraju provoditi u skladu s uvjetima ove licencije ili njezine buduće verzije, osim ako se izvorno djelo izričito distribuira samo u skladu s uvjetima ove verzije licence – primjerice ako je navedeno „Samo u skladu s uvjetima EUPL-a v. 1.2.” Nositelj licencije (koji postaje njezin davatelj) ne može pružiti ili nametnuti dodatne uvjete za djelo ili izvedena djela kojima se mijenjaju ili ograničavaju uvjeti licencije. + +Klauzula o kompatibilnosti: ako nositelj licencije distribuira ili stavlja na raspolaganje izvedena djela ili njihove kopije koji se temelje na originalnom djelu i nekom drugom djelu licenciranom u skladu s uvjetima kompatibilne licencije, te se aktivnosti moraju provoditi u skladu s uvjetima kompatibilne licencije. Za potrebe ove klauzule izraz „kompatibilne licencije” odnosi se na licencije navedene u dodatku ovoj licenciji. U slučaju da se obveze kompatibilnih licencija kose s obvezama ove licencije, primjenjuju se obveze kompatibilnih licencija. + +Dostavljanje izvornog koda: Pri distribuciji i stavljanju kopija djela na raspolaganje nositelj licencije dostavlja strojno čitljivu inačicu izvornog koda ili navodi repozitorij s pomoću kojeg se može jednostavno i besplatno pristupati izvornom kodu sve dok davatelj licencije distribuira ili stavljanja djelo na raspolaganje. + +Pravna zaštita: Ovom licencijom ne daje se odobrenje za uporabu trgovačkih imena, zaštićenih žigova, uslužnih žigova ili imena davatelja licencije, osim u mjeri koja je potrebna za razumnu i uobičajenu uporabu pri opisivanju izvora djela i reprodukcije sadržaja obavijesti o autorskom pravu. + +6.Niz autora +Izvorni davatelj licencije jamči da je nositelj autorskog prava djela za koje daje licenciju ili da je nositelj licencije za to djelo te da je ovlašten za davanje licencije. Svaki sudionik jamči da je nositelj autorskog prava za izmjene koje je unio u djelo ili da je nositelj licencije za te izmjene te da je ovlašten za davanje licencije. Svaki put kad prihvatite uvjete licencije, izvorni davatelj licencije i daljnji sudionici daju vam licenciju za svoje doprinose djelu u skladu s uvjetima ove licencije. + +7.Izjava o ograničenju jamstava +Djelo je „djelo u nastajanju”, koje neprestano poboljšavaju brojni sudionici. Ono nije dovršeno i zato može sadržavati nedostatke ili pogreške koje su svojstvene za tu vrstu razvoja. Stoga se djelo stavlja na raspolaganje „u postojećem stanju” te se ne daju nikakva jamstva u vezi s njim, uključujući, bez ograničenja, njegovu tržišnu kakvoću, prikladnost za svrhu, odsutnost nedostataka i pogrešaka, točnost, nekršenje prava intelektualnog vlasništva, osim autorskog prava kako je utvrđeno člankom 6. ove licencije. Ova izjava o ograničenju jamstava ključan je dio licencije i uvjet za dodjelu svih prava povezanih s djelom. + +8.Izjava o ograničenju odgovornosti +Osim u slučaju namjerne povrede ili štete izravno učinjene fizičkim osobama davatelj licencije ni u kojem slučaju neće se smatrati odgovornim za bilo kakvu izravnu ili neizravnu, materijalnu ili moralnu štetu nastalu na temelju licencije ili uporabe djela, uključujući, bez ograničenja, štetu povezanu s gubitkom dobrog glasa, prekidom rada, kvarom ili neispravnošću računala i gubitkom podataka te bilo koju drugu komercijalnu štetu, čak i ako je pružatelj licencije bio informiran o mogućnosti nastanka te štete. Međutim, pružatelj licencije smatra se odgovornim u skladu sa zakonskim propisima o odgovornosti za proizvode ako su ti propisi primjenjivi na djelo. + +9.Dodatni ugovori +Pri distribuciji djela možete sklopiti dodatni ugovor kojim se utvrđuju obveze ili usluge koje su u skladu s ovom licencijom. Međutim, ako prihvatite obveze, možete nastupati samo u vlastito ime i na vlastitu odgovornost, a ne uime izvornog davatelja licencije ili bilo kojeg drugog sudionika, te uz uvjet da prihvatite da se samim prihvaćanjem jamstava ili dodatnih odgovornosti obvezujete ostalim sudionicima nadoknaditi štetu, braniti ih i osloboditi odgovornosti u odnosu na nastalu obvezu ili potraživanja. + +10.Prihvaćanje licencije +Odredbe licencije prihvaćaju se klikom na gumb „Prihvaćam” koji se nalazi na dnu prozora u kojem je prikazan tekst ove licencije ili potvrđivanjem suglasnosti na sličan način u skladu s pravilima primjenjivog prava. Klikom na taj gumb jasno i neopozivo prihvaćate ovu licenciju i sve njezine uvjete. Isto tako, neopozivo prihvaćate ovu licenciju i sve njezine uvjete ako ostvarite bilo koje pravo koje vam je dodijeljeno člankom 2. ove licencije, kao što je korištenje djelom, izrada izvedenog djela ili distribucija ili stavljanje na raspolaganje djela ili njegovih kopija. + +11.Obavješćivanje javnosti +U slučaju distribucije djela ili njegova stavljanja na raspolaganje elektroničkom komunikacijom (npr. omogućivanje preuzimanja djela s udaljene lokacije), distribucijski kanal ili medij (npr. web mjesto) mora sadržavati barem informacije koje su obvezne u skladu s primjenjivim pravom o davatelju licencije, licenciji i načinu na koji joj nositelj licencije može pristupiti te je prihvatiti, pohraniti i reproducirati. + +12.Oduzimanje licencije +Licencija i dodijeljena prava automatski se oduzimaju ako nositelj odobrenja na bilo koji način postupi protivno uvjetima licencije. Oduzimanje se ne odnosi na osobe koje su licenciju za to djelo dobile od tog nositelja odobrenja u skladu s uvjetima licencije ako te osobe i dalje u potpunosti poštuju uvjete licencije. + +13.Razno +Ne dovodeći u pitanje članak 9. licencija čini potpuni ugovor između stranaka u pogledu djela. Ako određena odredba licencije nije valjana ili izvršiva u skladu s primjenjivim zakonom, to ne utječe na valjanost ili izvršivost licencije u cjelini. Takve odredbe bit će zamijenjene ili izmijenjene kako bi postale valjane i izvršive. Ako je to potrebno i razumno, Europska komisija može objaviti druge jezične verzije ili nove verzije ove licencije ili ažurirane verzije dodatka, a da se pritom ne smanji opseg prava dodijeljenih licencijom. Nove verzije licencije bit će objavljene s jedinstvenim brojem verzije. Sve jezične verzije ove licencije koje je odobrila Europska komisija imaju istu vrijednost. Stranke se mogu koristiti jezičnom verzijom prema vlastitom odabiru. + +14.Nadležnost +Ne dovodeći u pitanje poseban ugovor koje su stranke sklopile, svaki spor koji proizlazi iz tumačenja ove licencije, a nastao je: +— između bilo kojeg nositelja licencije i institucija, tijela, ureda i agencija Europske unije kao davatelja licencije u nadležnosti je Suda Europske unije, kako je utvrđeno člankom 272. Ugovora o funkcioniranju Europske unije, +— između drugih stranaka u isključivoj je nadležnosti mjerodavnog suda u zemlji u kojoj davatelj licencije boravi ili obavlja osnovnu djelatnost. + +15.Mjerodavno pravo +Ne dovodeći u pitanje poseban ugovor koje su stranke sklopile, ova je licencija uređena: +— pravom države članice Europske unije u kojoj davatelj licencije ima sjedište, boravak ili registrirani ured, +— belgijskim pravom ako davatelj licencije nema sjedište, boravak odnosno registrirani ured u državi članici Europske unije. + +Dodatak +„Kompatibilne licencije” u skladu s člankom 5. EUPL-a: +— GNU General Public License (GPL) v. 2., v. 3., +— GNU Affero General Public License (AGPL) v. 3., +— Open Software License (OSL) v. 2.1., v. 3.0., +— Eclipse Public License (EPL) v. 1.0., +— CeCILL v. 2.0., v. 2.1., +— Mozilla Public Licence (MPL) v. 2., +— GNU Lesser General Public Licence (LGPL) v. 2.1., v. 3., +— Creative Commons Attribution-ShareAlike v. 3.0. Unported (CC BY-SA 3.0) za djela koja nisu softver, +— Javna licencija Europske unije (EUPL) v. 1.1., v. 1.2., +— Javna licencija Québeca otvorenoga koda – uzajamnost (LiLiQ-R) ili snažna uzajamnost (LiLiQ-R+). +Europska unija može ažurirati dodatak u pogledu novih verzija prethodno navedenih licencija, a da pritom ne objavi novu verziju EUPL-a, uz uvjet da se tim licencijama pružaju prava zajamčena člankom 2. ove licencije, a obuhvaćeni izvorni kôd štiti od isključivog pripisivanja, +Sve ostale izmjene i dopune dodatka zahtijevaju novu verziju EUPL-a. 19.5.2017. L 128/64 Službeni list Europske unije HR diff --git a/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 HU.txt b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 HU.txt new file mode 100644 index 0000000..7c13bd5 --- /dev/null +++ b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 HU.txt @@ -0,0 +1,97 @@ +EURÓPAI UNIÓS NYILVÁNOS LICENC 1.2. verzió +EUPL © Európai Unió 2007, 2016 +Az Európai Uniós Nyilvános Licencet (a továbbiakban: „EUPL”) az annak rendelkezései szerint rendelkezésre bocsátott (az alábbiakban meghatározott) Művekre kell alkalmazni. A Művek e Licencben engedélyezettől eltérő felhasználása tilos (amennyiben az adott Mű szerzői jogi tulajdonosának valamely joga e felhasználásra kiterjed). A Művet e Licenc rendelkezései szerint bocsátják rendelkezésre, ha (az alábbi meghatározás szerinti) Licenciaadó a Műre vonatkozó szerzői jogi nyilatkozat után közvetlenül feltüntette az alábbi közleményt: + Licenc az EUPL szerint +vagy bármilyen egyéb formában az EUPL szerinti felhasználást engedélyező nyilatkozatot tett. +1.Fogalommeghatározások +E Licencben az alábbi fogalmak jelentése a következő: +— Licenc: e Licenc (felhasználási engedély). +— Eredeti Mű: a Licenciaadó által e Licenc alapján terjesztett vagy nyilvánossághoz közvetített mű vagy szoftver, amely Forráskódként, és – az esettől függően – Végrehajtható kódként áll rendelkezésre. +— Származékos Művek: azon művek vagy szoftverek, amelyeket a Hasznosító az Eredeti Mű vagy annak átdolgozásai alapján készíthet. E Licenc nem határozza meg, hogy az Eredeti Mű milyen mértékű átdolgozása vagy a Származékos Műnek az Eredeti Műtől való milyen mértékű függése szükséges ahhoz, hogy egy mű Származékos Műnek minősüljön; ezt a mértéket a 15. cikkben említett ország szerzői joga határozza meg. +— Mű: az Eredeti Mű vagy az az alapján létrejött Származékos Művek. +— Forráskód: a Mű ember által olvasható változata, amely az ember által való tanulmányozásra és a módosításra a legalkalmasabb. +— Végrehajtható kód: a Műnek bármely – általában – lefordított kódban létező formája, amelynek rendeltetése, hogy azt a számítógép programként értelmezze. +— Licenciaadó: az a természetes vagy jogi személy, aki/amely a Művet a Licenc alapján terjeszti vagy a nyilvánossághoz közvetíti. +— Közreműködő(k): az a természetes vagy jogi személy, aki/amely a Licenc alapján átdolgozza a Művet, vagy más módon hozzájárul a Származékos Mű megalkotásához. +— Hasznosító vagy „Ön”: az a természetes vagy jogi személy, aki/amely a Licenc feltételei szerint felhasználja a Művet. +— Terjesztés vagy Nyilvánossághoz Közvetítés: a Mű példányának adásvétele, birtokba adása, haszonkölcsönbe adása, bérbe adása, terjesztése, nyilvánossághoz közvetítése, átvitele vagy bármely egyéb módon, online vagy offline történő hozzáférhetővé tétele, illetve alapvető funkcióihoz való hozzáférés biztosítása harmadik, természetes vagy jogi személy részére. + +2.A Licenc által biztosított jogok terjedelme +A Licenciaadó az Eredeti Mű szerzői jogi védelmének időtartamára az egész világra kiterjedő, díjmentes, nem kizárólagos és harmadik személyeknek továbbengedélyezhető engedélyt ad Önnek az alábbi tevékenységekre: +— a Mű felhasználása tetszőleges körülmények között és bármilyen célra, +— a Mű sokszorosítása, +— a Mű átdolgozása, és a Műből Származékos Művek létrehozása, +— a Műnek vagy másolatainak a nyilvánossághoz való közvetítése, ideértve a nyilvánosság számára történő hozzáférhetővé tételt vagy nyilvános megjelenítést, illetve adott esetben a Mű nyilvános előadását, +— a Mű vagy a Mű másolatainak terjesztése, +— a Mű vagy a Mű másolatainak haszonkölcsönbe adása vagy bérbeadása, +— a Művön vagy a Mű másolatain fennálló jogok harmadik személynek történő továbbengedélyezése. +Az említett jogok gyakorlása lehetséges bármilyen jelenleg létező vagy még ismeretlen médium, hordozó és formátum igénybevételével, amennyiben ezt az alkalmazandó jog megengedi. Azokban az országokban, ahol elismerik a személyhez fűződő jogokat, a Licenciaadó az alkalmazandó jog által megengedett mértékben a fentiekben megnevezett vagyoni jogokra vonatkozó engedély akadálytalan gyakorlása céljából lemond a személyhez fűződő jogainak gyakorlásáról. A Licenciaadó díjmentes és nem kizárólagos használati engedélyt ad a Hasznosító számára a Licenciaadót megillető szabadalmak hasznosítására olyan mértékben, amely szükséges a Művön fennálló, e Licencben meghatározott jogok gyakorlásához. + +3.A Forráskód nyilvánossághoz való közvetítése +A Licenciaadó a Művet Forráskód, vagy Végrehajtható kód formájában bocsáthatja rendelkezésre. Ha a Művet Végrehajtható kódként bocsátotta rendelkezésre, a Hasznosító a Mű általa terjesztett valamennyi példányához köteles rendelkezésre bocsátani a Mű Forráskódjának géppel olvasható példányát, vagy a Műhöz csatolt szerzői jogi nyilatkozatot követő közleményben megadja azt a helyet, ahol a Forráskód egyszerűen és ingyenesen hozzáférhető mindaddig, amíg a Licenciaadó folytatja a Mű terjesztését vagy nyilvánossághoz közvetítését. + +4.A szerzői jog korlátai +E Licencben semmi sem irányul arra, hogy megfossza a Hasznosítót azoktól az előnyöktől, amelyek a Mű tulajdonosainak kizárólagos jogai alóli kivételeken vagy azok korlátain, kimerülésén vagy egyéb alkalmazandó korlátozásain alapulnak. + +5.A Hasznosító kötelezettségei +A fent felsorolt jogok gyakorlása csak akkor engedélyezhető, ha a Hasznosító betartja az alábbi korlátozásokat és kötelezettségeket. E kötelezettségek a következők: + +Feltüntetési kötelezettség: A Hasznosító köteles sértetlenül hagyni minden szerzői jogi, szabadalmi vagy védjegyjogra vonatkozó nyilatkozatot, továbbá minden más, a Licencre hivatkozó, valamint a szavatosság korlátozásával kapcsolatos nyilatkozatot. A Hasznosító köteles e nyilatkozatok és a Licenc egy példányát a terjesztett vagy a nyilvánossághoz közvetített Mű valamennyi másolatához hozzácsatolni. A Hasznosító köteles jól látható nyilatkozatot elhelyezni az általa átdolgozott Származékos Művön a Mű átdolgozására és az átdolgozás időpontjára vonatkozóan. + +„Copyleft”-kikötés: Amennyiben a Hasznosító az Eredeti Mű vagy Származékos Művek példányait terjeszti vagy a nyilvánossághoz közvetíti, e Terjesztés vagy Nyilvánossághoz Közvetítés csak e Licenc, illetve e Licenc egy későbbi verziójának feltételei szerint történhet, kivéve, ha az Eredeti Mű a Licencnek kizárólag e verziója alapján terjeszthető (például a „kizárólag EUPL 1.2. verzió” szöveg feltüntetése esetén). A Hasznosító (ebben az esetben Licenciaadóként) nem ajánlhat, illetve nem köthet ki a Műre vagy a Származékos Műre vonatkozóan olyan járulékos feltételeket, amelyek megváltoztatják vagy korlátozzák a Licenc feltételeit. + +Kompatibilis Licenc alkalmazása: Amennyiben a Hasznosító a Műből és egy másik, Kompatibilis Licenc alapján felhasznált Műből létrehozott Származékos Művet vagy e Származékos Mű másolatait terjeszti vagy a nyilvánossághoz közvetíti, e terjesztés vagy nyilvánossághoz közvetítés történhet a Kompatibilis Licenc feltételei alapján. E kikötés alkalmazásában Kompatibilis Licenc az e Licenchez csatolt függelékben felsorolt licenceket jelenti. Amennyiben a Hasznosító Kompatibilis Licenc szerinti kötelezettségei ellentétesek az e Licenc szerinti kötelezettségeivel, a Kompatibilis Licenc szerinti kötelezettségeket kell alkalmazni. + +A Forráskód rendelkezésre bocsátása: A Felhasználó a Mű példányainak terjesztése vagy nyilvánossághoz közvetítése során köteles rendelkezésre bocsátani a Forráskód géppel olvasható példányát vagy megjelölni azt a helyet, ahol a Forráskód egyszerűen és ingyenesen hozzáférhető mindaddig, amíg a Felhasználó a Mű terjesztését vagy nyilvánossághoz közvetítését folytatja. + +Jogvédelem: A Licenc nem ad engedélyt a Licenciaadót illető kereskedelmi név, védjegy, szolgáltatási védjegy, illetve a Licenciaadó nevének használatára, kivéve a Mű eredetének leírásához szükséges észszerű és szokásos, valamint a szerzői jogi nyilatkozat többszörözéséhez szükséges használatot. + +6.Szerzőségi láncolat (jogszavatosság) +Az eredeti Licenciaadó helytáll azért, hogy ő a felhasználásra engedélyezett Eredeti Mű szerzői jogosultja, vagy a szerzői jogok gyakorlására engedéllyel rendelkezik, és jogosult a Licenc szerinti engedély megadására. Valamennyi Közreműködő helytáll azért, hogy ő a Művön az általa végrehajtott átdolgozások szerzői jogosultja, vagy a szerzői jogok gyakorlására engedéllyel rendelkezik, és jogosult a Licenc szerinti engedély megadására. Minden alkalommal, amikor Ön elfogadja a Licencet, az eredeti Licenciaadó és az őt követő Közreműködők a Műhöz általuk nyújtott hozzájárulás felhasználására e Licenc feltételei szerinti engedélyt adnak Önnek. + +7.A szavatosság korlátozása +A Mű, amelyet számos közreműködő fejleszt, folyamatosan változik. Nem tekinthető befejezett műnek, emiatt az ilyen típusú fejlesztésre jellemző hiányosságokat vagy hibákat tartalmazhat. A fenti okok miatt a Művet a Licenc feltételei szerint „ahogy van” alapon és a Műre vonatkozó bármiféle szavatosság vállalása nélkül bocsátják rendelkezésre, ideértve különösen a piacképességre, valamely meghatározott célra való alkalmasságra, a hiányosságok és hibák hiányára, a pontosságra és a Licenc 6. cikkében említett szerzői jogokon kívüli szellemi tulajdonjogok sértetlenségére vonatkozó helytállás kizárását. A szavatosság korlátozására vonatkozó nyilatkozat a Licenc lényeges rendelkezése, és feltétele a Művön fennálló bármely jog engedélyezésének. + +8.Felelősségkorlátozás +A szándékosság vagy a természetes személyeknek okozott közvetlen károkozás esetét kivéve a Licenciaadó nem felel a Licencből vagy a Mű felhasználásából eredő semmilyen közvetlen vagy közvetett, vagyoni vagy nem vagyoni kárért, ideértve különösen az üzleti jó hírnév csorbításából, a termelés szüneteltetéséből, számítógépes meghibásodásból vagy üzemhibából, adatvesztésből eredő vagy kereskedelmi jellegű károkat, még abban az esetben sem, ha a Licenciaadót előzetesen figyelmeztették e károk bekövetkeztének lehetőségére. A Licenciaadó azonban a jogszabályban előírt termékfelelősséggel tartozik, amennyiben e szabályok a Műre alkalmazandók. + +9.Kiegészítő megállapodások +A Mű terjesztése során Ön e Lincenccel összhangban álló kötelezettség vállalására vagy egyéb szolgáltatások nyújtására vonatkozó kiegészítő megállapodást köthet. A kötelezettségeket azonban Ön nem az eredeti Licenciaadó vagy az egyéb Közreműködő nevében és terhére, hanem csak a saját nevében és felelősségére vállalhatja el, és kizárólag akkor, ha vállalja, hogy a Közreműködőket kártérítésben részesíti, illetve mentesíti azon felelősség, illetve a velük szemben érvényesített azon igények alól, amelyek az Ön által vállalt szavatossági helytállás vagy kiegészítő felelősség következtében keletkeztek. + +10.A Licenc elfogadása +E Licenc rendelkezéseit Ön elfogadhatja úgy, hogy az e Licenc szövegét tartalmazó ablak alatt található „Elfogadom” feliratú ikonra kattint, vagy ha az alkalmazandó jog rendelkezéseivel összhangban bármely más hasonló módon kifejezi a beleegyezésre irányuló akaratát. Ha Ön az ikonra kattint, az a Licenc és az abban foglalt valamennyi feltétel egyértelmű és visszavonhatatlan elfogadását jelenti. Ehhez hasonlóan e Licenc és az ebben foglalt valamennyi feltétel visszavonhatatlan elfogadását jelenti a Licenc 2. cikkében Önnek biztosított jogok gyakorlása, többek között Művek felhasználása, Származékos Mű Ön általi létrehozása, valamint Műveknek vagy példányainak Ön által történő terjesztése vagy nyilvánossághoz közvetítése. + +11.A nyilvánosság tájékoztatása +Amennyiben Ön a Művet elektronikus úton terjeszti vagy a nyilvánossághoz közvetíti (például a távolból való letöltésre kínálja fel), a terjesztési csatornának vagy médiumnak (például weboldalnak) legalább az alkalmazandó jog által előírt, a Licenciaadóra, a Licencre, valamint arra vonatkozó tájékoztatást kell közzétennie, hogy a Hasznosító miként férhet hozzá a Licenchez, azt hogyan fogadhatja el, tárolhatja, illetve sokszorosíthatja. + +12.A Licenc megszűnése +A Licenc és az abban biztosított jogosultságok automatikusan hatályukat vesztik, ha a Hasznosító a Licenc feltételeit bármely módon megszegi. E megszűnés nem eredményezi azon személyeknek adott engedélyek hatályának megszűnését, akiknek a Hasznosító a Licenc keretében bocsátotta rendelkezésre a Művet, feltéve, hogy e személyek továbbra is teljes mértékben eleget tesznek a Licenc feltételeinek. + +13.Egyebek +A fenti 9. cikk sérelme nélkül a Licenc a Műre nézve a felek közötti teljes és mindenre kiterjedő megállapodás. Ha a Licenc valamely rendelkezése az alkalmazandó jog szerint érvénytelen vagy kikényszeríthetetlen, ez nem érinti a Licenc mint egész érvényességét vagy kikényszeríthetőségét. Az ilyen rendelkezést az érvényességéhez és kikényszeríthetőségéhez szükséges módon kell értelmezni vagy módosítani. Az Európai Bizottság szükséges és indokolt esetben nyilvánosságra hozhatja e Licenc vagy a Függelék naprakész verzióinak más nyelvű fordításait vagy újabb változatait, ezek azonban nem korlátozhatják a Licenc által biztosított jogok hatályát. A Licenc új változatait egyedi verziószámmal teszik közzé. E Licenc bármely az Európai Bizottság által jóváhagyott más nyelvű fordítása azonos joghatással rendelkezik. A szerződő felek szabadon használhatják a Licenc általuk választott nyelvre fordított változatát. + +14.Joghatóság +A felek közötti konkrét megállapodás sérelme nélkül, +— az e Licenc értelmezéséből eredő bármely, az európai uniós intézmények, szervek, hivatalok és ügynökségek, mint Licenciaadó és bármely Hasznosító közötti jogvita az Európai Unió működéséről szóló szerződés 272. cikkének megfelelően az Európai Unió Bíróságának hatáskörébe tartozik, +— más felek közötti, e Licenc értelmezéséből eredő bármely jogvita azon ország megfelelő hatáskörrel rendelkező bíróságának kizárólagos illetékessége alá tartozik, ahol a Licenciaadó székhelye található, vagy ahol fő tevékenységét folytatja. + +15.Alkalmazandó jog +A felek közötti konkrét megállapodás sérelme nélkül, +— e licencre az Európai Unió azon tagállamának a joga alkalmazandó, ahol a Licenciaadó székhelye vagy lakóhelye található, +— ha a Licenciaadó nem rendelkezik székhellyel vagy lakóhellyel az Európai Unió valamelyik tagállamában, akkor e Licencre a belga jog alkalmazandó. + + +Függelék +Az EUPL 5. cikke szerinti „Kompatibilis licencek”: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) a szofverektől eltérő művek esetében +— European Union Public Licence (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence – Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+). +E Függeléket az Európai Bizottság a fent említett licencek későbbi verzióival naprakésszé teheti anélkül, hogy új EUPL-verziót kellene készítenie, feltéve, hogy a szóban forgó licencek biztosítják az e Licenc 2. cikkében foglalt jogokat, és védelmet nyújtanak az érintett Forráskód kizárólagos felhasználása ellen. +A Függelék minden egyéb jellegű módosítása vagy bővítése új EUPL-verzió kiadását teszi szükségessé. diff --git a/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 IT.txt b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 IT.txt new file mode 100644 index 0000000..05ffd80 --- /dev/null +++ b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 IT.txt @@ -0,0 +1,95 @@ +LICENZA PUBBLICA DELL'UNIONE EUROPEA v. 1.2 +EUPL © Unione europea 2007, 2016 +La presente Licenza Pubblica dell'Unione europea («EUPL») si applica a tutte le opere, come definite di seguito, fornite alle condizioni di cui alla presente licenza. È vietata l'utilizzazione dell'opera in forme diverse da quelle autorizzate dalla presente licenza (nella misura in cui tale utilizzazione sia riservata in via esclusiva al titolare dei diritti d'autore sull'opera). L'opera è fornita alle condizioni della presente licenza se il licenziante (come definito di seguito) ha posto la seguente dicitura immediatamente dopo l'avviso sui diritti d'autore sull'opera: + Concesso in licenza a norma dell'EUPL +o ha espresso con qualunque altro mezzo la propria volontà di cederla in licenza alle condizioni dell'EUPL. + +1 Definizioni +Nella presente licenza i seguenti termini sono così definiti: +— Licenza: la presente licenza. +— Opera originaria: l'opera o il software distribuiti o comunicati dal licenziante alle condizioni della presente licenza, disponibile sotto forma di codice sorgente e, a seconda dei casi, anche sotto forma di codice eseguibile. +— Opere derivate: le opere o il software che possono essere creati dal licenziatario sulla base dell'opera originaria o di una sua modificazione. La presente licenza non definisce quale grado di modificazione o di dipendenza rispetto all'opera originaria sia prescritto per caratterizzare un'opera come opera derivata; tale questione è disciplinata dalla legge sul diritto d'autore applicabile nel paese indicato all'articolo 15. +— Opera: l'opera originaria o le opere da essa derivate. +— Codice sorgente: forma leggibile dell'opera che risulta la più appropriata per essere studiata e modificata dall'uomo. +— Codice eseguibile: il codice che in genere è stato compilato e che è destinato a essere eseguito come programma da un computer. +— Licenziante: la persona fisica o giuridica che distribuisce o comunica l'opera secondo i termini della licenza. — Contributore/i:la persona fisica o giuridica che modifica l'opera secondo i termini della licenza o altrimenti contribuisce alla creazione di un'opera derivata. +— Licenziatario :la persona fisica o giuridica che fa uso del programma secondo i termini della licenza. +— Distribuzione o comunicazione: la vendita, la cessione a titolo gratuito, il prestito, la locazione, la distribuzione, la comunicazione, la trasmissione o qualsiasi altro atto finalizzato a mettere copie dell'opera a disposizione di altre persone fisiche o giuridiche, o fornire loro accesso alle sue funzionalità essenziali, online o offline. + +2 Estensione dei diritti concessi dalla licenza +Il licenziante concede al licenziatario, per tutta la durata del diritto d'autore sull'opera originaria, una licenza mondiale, gratuita, non esclusiva, a sua volta cedibile in sublicenza, che conferisce il diritto di compiere gli atti seguenti: +— utilizzare l'opera in qualsiasi circostanza e per ogni utilizzo, +— riprodurre l'opera, +— modificare l'opera e creare opere derivate basate su di essa, +— comunicare al pubblico, anche mediante messa a disposizione o esposizione dell'opera o di copie della stessa e, a seconda dei casi, rappresentare l'opera in forma pubblica, +— distribuire l'opera o copie della stessa, +— cedere in prestito e in locazione l'opera o copie della stessa, +— concedere in sublicenza i diritti sull'opera o copie della stessa. +I diritti suddetti possono essere esercitati con qualsiasi mezzo di comunicazione, su qualsiasi supporto e in qualsiasi formato, attualmente noto o che sarà successivamente inventato, nella misura consentita dal diritto applicabile. Nei paesi in cui si applicano i diritti morali di autore, il licenziante rinuncia al diritto di esercitare i suoi diritti morali nella misura consentita dalla legge affinché la cessione in licenza dei diritti patrimoniali sopra indicati possa produrre tutti i suoi effetti. Il licenziante concede al licenziatario, a titolo gratuito e non esclusivo, il diritto di utilizzare qualsiasi brevetto detenuto dal licenziante, nella misura necessaria all'esercizio dei diritti di utilizzazione dell'opera concessi dalla presente licenza. + +3 Comunicazione del codice sorgente +Il licenziante può fornire l'opera o sotto forma di codice sorgente o come codice eseguibile. Se l'opera è fornita come codice eseguibile, il licenziante fornisce, in aggiunta, una copia leggibile dall'elaboratore del codice sorgente dell'opera a corredo di ogni copia dell'opera da lui distribuita oppure indica, in un avviso che segue l'avviso sui diritti d'autore apposto sull'opera, un archivio in cui il codice sorgente è facilmente e gratuitamente accessibile per tutto il periodo in cui il licenziante distribuisce o comunica l'opera. + +4 Limitazioni del diritto d'autore +Nessuna clausola della presente licenza è finalizzata a impedire al licenziatario di beneficiare di tutte le eccezioni o limitazioni applicabili ai diritti esclusivi dei titolari dei diritti sull'opera, dell'esaurimento di tali diritti o di qualsiasi altra limitazione applicabile. + +5 Obblighi del licenziatario +La concessione dei diritti sopra indicati è soggetta ad alcune restrizioni e obblighi in capo al licenziatario. Gli obblighi sono i seguenti: + +Diritto di attribuzione: il licenziatario lascia intatti tutti gli avvisi relativi ai diritti d'autore, ai brevetti o ai marchi e tutte le indicazioni che fanno riferimento alla licenza e all'esclusione della garanzia. Ogni copia dell'opera che il licenziatario distribuisce o comunica deve essere corredata di una copia di tali avvisi e di una copia della licenza. Su tutte le opere derivate il licenziatario deve apporre o far apporre avvisi ben visibili indicanti che l'opera è stata modificata e la data della modificazione. + +Clausola «copyleft»: se il licenziatario distribuisce o comunica copie delle opere originarie o delle opere derivate, la distribuzione o comunicazione ha luogo nell'osservanza delle clausole della presente licenza o di una sua versione successiva a meno che l'opera originaria venga esplicitamente distribuita solo nel quadro della presente versione della licenza, ad esempio mediante la comunicazione «solo EUPL v. 1.2». Il licenziatario (che in tal caso diventa licenziante) non può offrire né imporre termini o condizioni ulteriori sull'opera o sulle opere derivate che alterino o restringano le condizioni della licenza. + +Clausola di compatibilità: se il licenziatario distribuisce o comunica le opere derivate o copie delle opere derivate basate sull'opera e su un'altra opera concessa in licenza secondo le condizioni di una licenza compatibile, la distribuzione o comunicazione può avvenire nell'osservanza delle clausole della licenza compatibile. Ai fini dell'applicazione della presente clausola, l'espressione «licenza compatibile» si riferisce alle licenze enumerate nell'allegato della presente licenza. In caso di conflitto tra gli obblighi del licenziatario a norma della licenza compatibile e i suoi obblighi a norma della presente licenza, prevalgono gli obblighi prescritti dalla licenza compatibile. + +Fornitura del codice sorgente: se distribuisce o comunica copie dell'opera, il licenziatario fornirà copia del codice sorgente in formato leggibile dall'elaboratore oppure indicherà un archivio in cui tale codice sorgente è facilmente e liberamente accessibile, per tutto il tempo in cui distribuisce o comunica l'opera. + +Tutela dei diritti: la presente licenza non autorizza a fare uso di nomi commerciali, di marchi distintivi di prodotti o servizi o dei nomi dei licenzianti, se non nei limiti necessari ad una utilizzazione ragionevole e conforme agli usi per descrivere l'origine dell'opera e riprodurre il contenuto dell'avviso relativo al diritto d'autore. + +6 Autori e contributori +Il licenziante originario garantisce che i diritti d'autore sull'opera originaria concessi a norma della presente licenza sono di sua proprietà ovvero gli sono concessi in licenza e che dispone del diritto e del potere di concedere la licenza. Ciascun contributore garantisce che i diritti d'autore sulle modifiche che egli apporta all'opera sono di sua proprietà o che gli sono concessi in licenza e che dispone del diritto e del potere di concedere la licenza. Ogni volta che il licenziatario accetta la licenza, il licenziante originario e i contributori successivi concedono al licenziatario una licenza sui loro contributi all'opera, secondo le condizioni della presente licenza. + +7 Esclusione della garanzia +L'opera è un'opera in divenire, che viene costantemente migliorata grazie all'apporto di diversi contributori. Non si tratta di un'opera finita e può pertanto contenere difetti o errori inerenti a questo tipo di sviluppo. Per tale ragione, l'opera è concessa in licenza «così com'è» e senza garanzie di alcun genere, ivi incluse, tra le altre, quelle relative all'utilizzazione commerciale, all'idoneità a soddisfare una determinata funzione, all'assenza di difetti o errori, all'accuratezza, all'efficacia, alla non violazione di diritti di proprietà intellettuale diversi dal diritto d'autore come indicato all'articolo 6 della presente licenza. La presente esclusione di garanzia costituisce parte integrante della licenza e condizione per la concessione di qualsiasi diritto sull'opera. + +8 Esclusione di responsabilità +Salvi i casi di comportamenti dolosi o di danni direttamente arrecati a persone fisiche, in nessun caso il licenziante può essere ritenuto responsabile per i danni, di qualsiasi natura, diretti o indiretti, materiali o morali, derivanti dalla licenza o dall'utilizzazione dell'opera, ivi inclusi, tra gli altri, i danni per perdita di avviamento, interruzione del lavoro, guasto o malfunzionamento del computer, perdita di dati e qualsiasi danno commerciale, anche nel caso in cui il licenziante fosse stato informato che tali danni avrebbero potuto verificarsi. Tuttavia, il licenziante sarà ritenuto responsabile a norma delle leggi sulla responsabilità da prodotto in quanto applicabili all'opera. + +9 Altre pattuizioni +All'atto della distribuzione dell'opera, il licenziatario ha facoltà di stipulare pattuizioni aggiuntive, definendo gli obblighi o i servizi compatibili con la presente licenza. Tuttavia, nell'accettare tali obblighi, il licenziatario agisce esclusivamente in nome proprio e sotto propria esclusiva responsabilità, e non in nome del licenziante originario o di qualsiasi altro contributore, e solo subordinatamente all'assunzione dell'impegno a risarcire, difendere e tenere indenne ciascun contributore da eventuali responsabilità o richieste risarcitorie rivolte allo stesso contributore in conseguenza delle garanzie o responsabilità aggiuntive assunte dal licenziatario. + +10 Accettazione della licenza Le clausole della presente licenza possono essere accettate cliccando sull'icona «Accetto» posta sotto una finestra che fa apparire il testo della presente licenza o prestando consenso in qualsiasi altro modo simile, conformemente alle disposizioni di legge applicabili. Cliccando su tale icona il licenziatario manifesta la chiara e irrevocabile accettazione della presente licenza e di tutti i suoi termini e condizioni. Analogamente accetta irrevocabilmente la presente licenza e tutti i suoi termini e condizioni esercitando i diritti concessi dall'articolo 2 della presente Licenza, quali l'utilizzazione dell'opera, la creazione di un'opera derivata o la distribuzione o comunicazione dell'opera o di copie della stessa. + +11 Informazione del pubblico +Se il licenziatario procede alla distribuzione o comunicazione dell'opera mediante strumenti di comunicazione elettronica (ad esempio, offrendo di scaricare l'opera da un luogo remoto), il canale di distribuzione o i mezzi di comunicazione (ad esempio un sito web) dovranno fornire al pubblico come minimo le informazioni prescritte dalla normativa applicabile in relazione al licenziante, alla licenza e al modo in cui essa può essere resa accessibile, accettata, conservata e riprodotta da parte del licenziatario. + +12 Cessazione della licenza +La licenza e i diritti da essa concessi cesseranno automaticamente di avere effetto ove il licenziatario violi una qualsiasi delle condizioni previste dalla licenza. Tale cessazione non comporterà cessazione delle licenze concesse a persone che abbiano ricevuto l'opera dal licenziatario a norma della licenza, sempreché tali persone ottemperino integralmente alle clausole della licenza stessa. + +13 Varie +Ferme restando le disposizioni dell'articolo 9, la licenza costituisce l'accordo integrale tra le parti in merito all'opera. Le clausole della licenza che risultino nulle o non possano essere fatte valere in base alla normativa applicabile non incideranno sulla validità o sull'applicabilità della licenza nel suo complesso. Le clausole in questione saranno interpretate o modificate nella misura necessaria a renderle valide e applicabili. La Commissione europea può pubblicare altre versioni linguistiche o nuove versioni della presente licenza o versioni aggiornate dell'Appendice, nella misura in cui ciò sia necessario e ragionevole, senza ridurre la portata dei diritti accordati dalla licenza. Le nuove versioni della licenza saranno pubblicate con un numero di versione univoco. Tutte le versioni linguistiche della presente licenza, approvate dalla Commissione europea, hanno valore identico. Le parti possono utilizzare la versione linguistica di loro scelta. + +14 Competenza giurisdizionale +Fatti salvi accordi specifici tra le parti: +— per qualsiasi controversia in ordine all'interpretazione della presente licenza che insorga tra le istituzioni, gli organismi, gli uffici e le agenzie dell'Unione, nella qualità di licenziante, e il licenziatario è competente la Corte di giustizia dell'Unione europea, a norma dell'articolo 272 del trattato sul funzionamento dell'Unione europea; +— per qualsiasi controversia che insorga tra altre parti in ordine all'interpretazione della presente licenza è esclusivamente competente il tribunale del luogo in cui il licenziante risiede o esercita la sua attività principale. + +15 Legge applicabile +Fatti salvi accordi specifici tra le parti: +— la presente Licenza è disciplinata dalla legge dello Stato membro dell'Unione europea nel quale il licenziante è stabilito, risiede o ha la propria sede sociale; +— la presente licenza è disciplinata dalla legge belga ove il licenziante non sia stabilito, non risieda o non abbia la propria sede sociale in uno Stato membro dell'Unione europea. + +Appendice +«Licenze compatibili» ai sensi dell'articolo 5 EUPL sono le seguenti: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) per le opere diverse dal software +— European Union Public Licence (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+). +La Commissione può aggiornare la presente Appendice per tener conto delle versioni più recenti delle licenze summenzionate senza produrre una nuova versione dell'EUPL, purché esse garantiscano i diritti concessi dall'articolo 2 della presente licenza e proteggano il codice sorgente coperto dall'appropriazione esclusiva. +Tutte le altre modifiche o aggiunte a tale Appendice richiedono la produzione di una nuova versione dell'EUPL. \ No newline at end of file diff --git a/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 LT.txt b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 LT.txt new file mode 100644 index 0000000..e8c733b --- /dev/null +++ b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 LT.txt @@ -0,0 +1,93 @@ +EUROPOS SĄJUNGOS VIEŠOJI LICENCIJA v. 1.2 +EUPL © Europos Sąjunga, 2007, 2016 +Ši Europos Sąjungos viešoji licencija (toliau – EUPL) taikoma kūriniui (kaip apibrėžta toliau), kuriuo naudotis leidžiama šioje licencijoje nustatytomis sąlygomis. Kūrinį naudoti kitaip, nei numatyta šioje licencijoje, draudžiama (tiek, kiek tokiam naudojimui taikomos kūrinio autoriaus teisių turėtojo teisės). Kūrinį leidžiama naudoti šioje licencijoje nustatytomis sąlygomis, kai licenciaras (kaip apibrėžta toliau) po kūrinio autoriaus teisių nuorodos pateikia šią nuorodą: + Licencijuota pagal EUPL +arba kitomis priemonėmis išreiškia savo norą leisti jį naudoti pagal EUPL. + +1.Apibrėžtys +Šioje licencijoje vartojamų terminų apibrėžtys: +— licencija–ši licencija, +— originalus kūrinys–šioje licencijoje nustatytomis sąlygomis licenciaro platinamas arba perduodamas kūrinys arba programinė įranga, gaunama kaip pirminis kodas ir, atsižvelgiant į aplinkybes, kaip vykdomasis kodas, +— išvestiniai kūriniai–kūriniai arba programinė įranga, kuriuos licenciatas galėtų sukurti remdamasis originaliu kūriniu arba jo pakeitimais. Šioje licencijoje neapibrėžiama, koks turi būti pakeitimų arba priklausomumo nuo originalaus kūrinio mastas, kad kūrinys būtų laikomas išvestiniu kūriniu; toks mastas apibrėžiamas autorių teisių įstatymuose, taikomuose 15 straipsnyje minimoje valstybėje, +— kūrinys – originalus kūrinys arba jo išvestiniai kūriniai, +— pirminis kodas – žmonėms suprantama kūrinio forma, kurią patogiausia nagrinėti ir keisti, +— vykdomasis kodas – bet koks įprastai sukompiliuotas kodas, kurį kompiuteris gali vykdyti kaip programą, — licenciaras–licencijoje nustatytomis sąlygomis kūrinį platinantis ir (arba) perduodantis fizinis arba juridinis asmuo, +— bendraautoris (-iai) – bet kuris fizinis arba juridinis asmuo, kuris licencijoje nustatytomis sąlygomis kūrinį keičia arba kitaip prisideda prie išvestinio kūrinio sukūrimo, +— licenciatas (arba jūs) – bet kuris fizinis arba juridinis asmuo, kuris licencijoje nustatytomis sąlygomis naudojasi kūriniu, +— platinimas arba perdavimas–kūrinio kopijų pardavimas, perleidimas, paskolinimas, nuoma, platinimas, pateikimas, persiuntimas arba kitoks suteikimas prijungties arba atjungties režimu arba prieigos prie jo pagrindinių funkcijų suteikimas naudotis bet kuriam kitam fiziniam arba juridiniam asmeniui. + +2.Licencija suteiktų teisių taikymo sritis +Šiuo dokumentu licenciaras suteikia jums be autorinio atlyginimo neišimtinę, sublicencijuojamą licenciją visame pasaulyje vykdyti toliau nurodytą veiklą tol, kol saugomos originalaus kūrinio autoriaus teisės: +— kūriniu naudotis bet kokiomis sąlygomis ir bet kokiais tikslais, +— kūrinį atgaminti, +— keisti kūrinį ir kurti kūriniu pagrįstus išvestinius kūrinius, +— kūrinį paskelbti, įskaitant teisę kūrinį arba jo kopijas pateikti visuomenei arba viešai rodyti ir, atsižvelgiant į aplinkybes, viešai atlikti, +— kūrinį arba jo kopijas platinti, +— kūrinį arba jo kopijas skolinti ir nuomoti, +— sublicencijuoti teises į kūrinį arba jo kopijas. +Jei tai leidžiama galiojančiais įstatymais, šios teisės gali būti taikomos bet kokioms laikmenoms, įrangai ir formatams, kurie jau žinomi arba bus vėliau išrasti. Valstybėse, kuriose taikomos neturtinės autoriaus teisės, licenciaras atsisako teisės naudotis savo neturtinėmis autoriaus teisėmis, kiek tai leidžiama teisės aktais, kad galėtų suteikti pirmiau išvardytų ekonominių teisių licenciją. Licenciaras suteikia licenciatui neišimtines teises be autorinio atlyginimo naudotis visais licenciaro turimais patentais tiek, kiek tai būtina, kad būtų galima naudotis pagal šią licenciją suteiktomis teisėmis į kūrinį. + +3.Pirminio kodo perdavimas +Licenciaras kūrinį gali pateikti kaip pirminį kodą arba kaip vykdomąjį kodą. Jei kūrinys pateikiamas kaip vykdomasis kodas, licenciaras su kiekviena jo platinamo kūrinio kopija taip pat pateikia kūrinio pirminio kodo kopiją, pritaikytą skaityti techninėmis priemonėmis, arba po kūrinio autoriaus teisių nuorodos nurodo saugyklą, kurioje pirminis kodas lengvai ir be užmokesčio prieinamas tol, kol licenciaras platina arba perduoda kūrinį. 4.Autoriaus teisių apribojimai Jokia šios licencijos nuostata nesiekiama atimti iš licenciato naudos, gaunamos dėl kūrinio teisių turėtojų išimtinių teisių išimčių arba apribojimų, dėl teisių išnaudojimo arba joms taikomų apribojimų. + +5.Licenciato pareigos +Pirmiau nurodytos teisės suteikiamos su sąlyga, kad licenciatui nustatomi tam tikri apribojimai ir pareigos. Šios pareigos yra tokios: + +Autorystės nuoroda. Licenciatas nekeičia jokių autoriaus teisių, patento arba prekės ženklų nuorodų ir jokių nuorodų, kuriuose minima licencija ir garantijų ribojimas. Tokių nuorodų kopiją ir licencijos kopiją licenciatas privalo pridėti prie kiekvienos jo platinamo arba perduodamo kūrinio kopijos. Licenciatas privalo užtikrinti, kad kiekviename išvestiniame kūrinyje būtų aiškiai pranešama, kad kūrinys pakeistas, ir nurodoma pakeitimo data. + +Nuostata dėl kopijavimo teisės išsaugojimo (Copyleft). Jei licenciatas platina arba perduoda originalių kūrinių arba išvestinių kūrinių kopijas, šis platinimas arba perdavimas vykdomas pagal šioje licencijoje arba vėlesnės redakcijos licencijoje nustatytas sąlygas, nebent originalus kūrinys platinamas aiškiai tik pagal šios redakcijos licenciją – pavyzdžiui, nurodant „tik EUPL v. 1.2“. Licenciatas (tampantis licenciaru) kūriniui arba išvestiniam kūriniui negali nustatyti arba taikyti jokių papildomų sąlygų, kuriomis būtų pakeistos arba apribotos šios licencijos sąlygos. + +Nuostata dėl analogiškumo. Jei licenciatas platina arba perduoda ir kūriniu, ir kitu analogišką licenciją turinčiu kūriniu pagrįstus išvestinius kūrinius arba jų kopijas, toks platinimas arba perdavimas gali būti vykdomas pagal toje analogiškoje licencijoje nustatytas sąlygas. Šioje nuostatoje „analogiška licencija“ – tai viena iš šios licencijos priedėlyje nurodytų licencijų. Jei analogiškoje licencijoje nustatytos licenciato pareigos prieštarauja šioje licencijoje nustatytoms jo pareigoms, vykdomos analogiškoje licencijoje nustatytos pareigos. + +Pirminio kodo suteikimas. Platindamas arba perduodamas kūrinio kopijas, licenciatas turi suteikti pirminio kodo kopiją, pritaikytą skaityti techninėmis priemonėmis, arba nurodyti saugyklą, kurioje šis pirminis kodas lengvai ir be užmokesčio prieinamas tol, kol licenciaras platina arba perduoda kūrinį. + +Teisinė apsauga. Šia licencija nesuteikiamas leidimas naudoti prekių pavadinimų, prekių ženklų, paslaugų ženklų arba licenciato pavadinimų (vardų, pavardžių), išskyrus atvejus, kai to pagrįstai ir įprastai reikia kūrinio kilmei nurodyti ir autoriaus teisių nuorodos turiniui atgaminti. + +6.Autorystės seka +Pirminis licenciaras užtikrina, kad jis turi šiuo dokumentu suteiktas originalaus kūrinio autoriaus teises arba tos teisės jam suteiktos pagal licenciją ir kad jis turi teisę ir įgaliojimus suteikti šią licenciją. Kiekvienas bendraautoris užtikrina, kad jo padarytų kūrinio pakeitimų autoriaus teisės priklauso jam arba tos teisės jam suteiktos pagal licenciją ir kad jis turi teisę ir įgaliojimus suteikti šią licenciją. Kiekvieną kartą jums sutikus su šia licencija, pirminis licenciaras ir paskesni bendraautoriai suteikia jums licenciją naudotis jų indėliu į kūrinį šioje licencijoje nustatytomis sąlygomis. + +7.Garantijų ribojimas +Kūrinys vis dar kuriamas, jį nuolat tobulina daug bendraautorių. Jis nėra baigtinis, todėl jame gali būti trūkumų arba programos klaidų, būdingų tokiam kūrimo būdui. Dėl pirmiau nurodytos priežasties kūrinys pagal licenciją pateikiamas „toks, koks yra“ ir be jokių su kūriniu susijusių garantijų, įskaitant (be apribojimų) tinkamumo prekybai, tinkamumo tam tikram tikslui, trūkumų arba klaidų nebuvimo, tikslumo, kitų intelektinės nuosavybės teisių nei autoriaus teisės, kaip nustatyta šios licencijos 6 straipsnyje, nepažeidimo garantijas. Toks garantijų ribojimas yra esminė šios licencijos dalis ir bet kokių teisių į kūrinį suteikimo sąlyga. + +8.Atsakomybės ribojimas +Išskyrus tyčinius nusižengimus arba tiesioginę fiziniams asmenims padarytą žalą, licenciaras nėra atsakingas už jokią tiesioginę ar netiesioginę materialinę ar moralinę žalą, padarytą dėl šios licencijos arba naudojant kūrinį, įskaitant (be apribojimų) žalą dėl prarasto prestižo, nutraukto darbo, kompiuterių gedimo arba trikdžių, prarastų duomenų arba bet kokią komercinę žalą, net jei licenciarui buvo pranešta apie tokios žalos galimybę. Tačiau licenciaras atsako pagal įstatymus, kuriais nustatoma atsakomybė už gaminių kokybę, kiek tokie įstatymai taikomi kūriniui. + +9.Papildomi susitarimai +Platindami kūrinį, jūs galite nuspręsti sudaryti papildomą susitarimą, kuriame būtų apibrėžti šios licencijos nuostatas atitinkantys įsipareigojimai arba paslaugos. Tačiau, jei prisiimate įsipareigojimus, jūs galite veikti tik savo, o ne pirminio licenciaro ar bet kurio kito bendraautorio vardu bei savo atsakomybe, ir tik jei sutinkate atlyginti nuostolius, ginti kiekvieną bendraautorį ir užtikrinti, kad dėl atsakomybės ir pretenzijų, reiškiamų dėl to, kad jūs sutikote su garantija arba prisiėmėte papildomą atsakomybę, jis nepatirtų žalos. + +10.Sutikimas su licencijos nuostatomis +Su šios licencijos nuostatomis galite sutikti spustelėdami piktogramą „Sutinku“, esančią lango, kuriame pateikiamas šios licencijos tekstas apačioje, arba patvirtindami savo sutikimą bet kuriuo kitu panašiu būdu pagal taikomų teisės aktų taisykles. Piktogramos spustelėjimas reiškia, kad aiškiai ir neatšaukiamai sutinkate laikytis šios licencijos nuostatų ir visų jos sąlygų. Lygiai taip pat, naudodamiesi bet kuria šios licencijos 2 straipsnyje jums suteikta teise, pavyzdžiui, teise naudotis kūriniu, kurti išvestinį kūrinį arba platinti arba perduoti kūrinį arba jo kopijas, jūs neatšaukiamai sutinkate laikytis visų šios licencijos nuostatų ir sąlygų. + +11.Informacijos teikimas visuomenei +Jei kūrinį platinate arba perduodate elektroninio ryšio priemonėmis (pavyzdžiui, siūlote kūrinį atsisiųsti iš nuotolinės buvimo vietos), platinimo kanale arba laikmenoje (pavyzdžiui, tinklalapyje) visuomenei turi būti pateikta bent tokia informacija, kuri yra būtina pagal taikomus įstatymus dėl licenciaro, licencijos ir dėl to, kaip licenciatas gali ją gauti, priimti, saugoti ir atgaminti. + +12.Licencijos galiojimo nutraukimas +Licencija ir ja suteiktos teisės nustoja galioti iš karto, kai licenciatas pažeidžia šios licencijos sąlygas. Nepaisant tokio galiojimo nutraukimo, toliau galioja visų licencijoje nustatytomis sąlygomis iš licenciato kūrinį gavusių asmenų turimos licencijos, jei tokie asmenys ir toliau visapusiškai laikosi licencijos sąlygų. + +13.Kita +Nepažeidžiant 9 straipsnio, ši licencija – tai visiškas šalių susitarimas dėl šiuo dokumentu licencijuojamo kūrinio. Jei kuri nors licencijos nuostata pagal taikomus įstatymus negalioja arba jos vykdymas tais įstatymais neužtikrinamas, tai neturi jokio poveikio visos licencijos galiojimui arba vykdymo užtikrinimui. Tokia nuostata turi būti aiškinama arba pataisyta taip, kad galiotų ir būtų užtikrintas jos vykdymas. Prireikus dėl pagrįstų priežasčių Europos Komisija gali paskelbti šios licencijos tekstą kitomis kalbomis arba naujas jos teksto ar priedėlio redakcijas, nesusiaurinusi šia licencija suteikiamų teisių. Naujos šios licencijos teksto redakcijos turi būti skelbiamos su nesikartojančiais teksto redakcijos numeriais. Visi Europos Komisijos patvirtinti šios licencijos teksto vertimai yra lygiareikšmiai. Šalys gali rinktis, kurio teksto vertimo laikytis. + +14.Jurisdikcija +Nepažeidžiant konkretaus šalių susitarimo, +— bet kokius Europos Sąjungos institucijų, įstaigų, organų ar agentūrų, kaip licenciarų, ir bet kurio licenciato teisinius ginčus dėl šios licencijos aiškinimo sprendžia Europos Sąjungos Teisingumo Teismas, kaip nustatyta Sutarties dėl Europos Sąjungos veikimo 272 straipsnyje, +— bet kokius kitų šalių teisinius ginčus dėl šios licencijos aiškinimo sprendžia išimtinę jurisdikciją turintis kompetentingas teismas, nustatomas pagal licenciaro gyvenamąją arba pagrindinės veiklos vykdymo vietą. + +15.Taikomi teisės aktai +Nepažeidžiant konkretaus šalių susitarimo, +— šiai licencijai taikomi tos Europos Sąjungos valstybės narės, kurioje licenciaras turi būstinę, yra įsikūręs arba turi registruotą buveinę, teisės aktai, +— jei licenciaras jokioje Europos Sąjungos valstybėje narėje neturi būstinės, nėra įsikūręs arba neturi registruotos buveinės, šiai licencijai taikomi Belgijos teisės aktai. + +Priedėlis +Pagal EUPL 5 straipsnį analogiškos licencijos yra: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) – kitiems kūriniams (ne programinei įrangai) +— Europos Sąjungos viešoji licencija (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence – Reciprocity (LiLiQ-R) arba Strong Reciprocity (LiLiQ-R+). +Siekdama priedėlyje nurodyti naujesnes pirma išvardytų licencijų redakcijas, Europos Komisija jį gali atnaujinti nerengdama naujos EUPL redakcijos, jei tose naujesnėse redakcijose numatomos pagal šios licencijos 2 straipsnį suteiktos teisės, o pirminis kodas apsaugomas nuo pasisavinimo pasinaudojant išimtinėmis teisėmis. +Dėl visų kitų šio priedėlio pakeitimų ar papildymų būtina parengti naują EUPL redakciją. 2017 5 19 L 128/64 Europos Sąjungos oficialusis leidinys LT diff --git a/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 LV.txt b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 LV.txt new file mode 100644 index 0000000..09f2410 --- /dev/null +++ b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 LV.txt @@ -0,0 +1,97 @@ +EIROPAS SAVIENĪBAS SABIEDRISKĀ LICENCE 1.2. redakcija +EUPL © Eiropas Savienība, 2007, 2016 +Eiropas Savienības sabiedriskā licence (EUPL) attiecas uz darbu (saskaņā ar turpmāk sniegto definīciju), kas izmantojams saskaņā ar šīs licences noteikumiem. Darbu ir atļauts izmantot tikai šajā licencē paredzētajā veidā (ciktāl uz šādu lietojumu attiecas darba autortiesību subjekta tiesības). Darbs ir izmantojams saskaņā ar šīs licences noteikumiem, ja licenciārs (saskaņā ar turpmāk sniegto definīciju) pēc darba autortiesību zīmes ir pievienojis šādu norādi: + Licencēts saskaņā ar EUPL +vai jebkādā citā veidā ir izteicis vēlēšanos darbu licencēt saskaņā ar EUPL. + +1.Definīcijas +Šajā licencē turpmāk minētos terminus lieto šādā nozīmē: +— “licence” ir šī licence, +— “oriģināldarbs” ir darbs vai programmatūra, kuru licenciārs izplata vai dara pieejamu saskaņā ar šo licenci un kurai ir pieejams pirmkods un attiecīgā gadījumā arī izpildkods, +— “atvasināti darbi” ir darbi vai programmatūra, ko licenciāts var radīt, balstoties uz oriģināldarbu vai tā pārveidojumiem. Šī licence nenosaka nepieciešamo pārveidojumu apmēru vai to, cik lielā mērā darbam jābūt saistītam ar oriģināldarbu, lai to atzītu par atvasinātu darbu; šis apmērs ir noteikts autortiesību regulējuma tiesību aktos, kas piemērojami 15. pantā minētajā valstī, +— “darbs” ir oriģināldarbs vai no tā atvasināti darbi, +— “pirmkods” ir darbs tādā cilvēkam lasāmā formā, kas ir visparocīgākā, lai cilvēki varētu to pētīt un pārveidot, +— “izpildkods” ir jebkurš kompilēts kods, kas ir paredzēts, lai dators to izpildītu kā programmu, +— “licenciārs” ir fiziska vai juridiska persona, kas darbu izplata vai dara zināmu saskaņā ar licenci, +— “attīstītājs” ir jebkura fiziska vai juridiska persona, kas saskaņā ar licenci izmantojamo darbu pārveido vai citādi iegulda atvasināta darba radīšanā, +— “licenciāts” vai “jūs” ir jebkura fiziska vai juridiska persona, kas atbilstoši licences noteikumiem darbu izmanto, +— “izplatīt” vai “darīt zināmu” ir veikt jebkuru darbību, ar kuru darba kopijas pārdod, dāvina, patapina, iznomā, izplata, dara zināmas, pārraida vai dara pieejamas citādā veidā, tiešsaistē vai bezsaistē, vai dod piekļuvi tā būtiskākajām funkcijām jebkurai fiziskai vai juridiskai personai. + +2.Ar licenci piešķirto tiesību apjoms +Ar šo licenciārs uz oriģināldarbam piemērojamo autortiesību aizsardzības laika posmu jums piešķir visā pasaulē izmantojamu vienkāršu bezatlīdzības licenci, ko var nodot trešām personām, šādām darbībām: +— izmantot darbu jebkādos apstākļos un bez ierobežojumiem, +— reproducēt darbu, +— pārveidot darbu un radīt atvasinātus darbus, izmantojot darbu, +— darīt zināmu sabiedrībai, tostarp darīt pieejamu vai izlikt apskatei, darbu vai tā kopijas un attiecīgā gadījumā darbu izpildīt publiski, +— izplatīt darbu vai tā kopijas, +— patapināt un iznomāt darbu vai tā kopijas, +— nodot licenci darba vai tā kopiju izmantošanai trešām personām. +Minētās tiesības var īstenot ar jebkuriem informācijas līdzekļiem, nesējiem un formātiem, kas šobrīd zināmi vai kurus nākotnē izgudros, ciktāl to atļauj piemērojamie tiesību akti. Valstīs, kurās eksistē autora personiskās tiesības, licenciārs atsakās īstenot savas autora personiskās tiesības, ciktāl to atļauj tiesību akti un ciktāl tas ir nepieciešams, lai nodrošinātu efektīvu iepriekš minēto autora mantisko tiesību realizāciju. Licenciārs bez tiesībām uz atlīdzību un bez izņēmuma tiesībām piešķir licenciātam visu licenciāra patentu lietošanas tiesības, ciktāl tas ir nepieciešams, lai realizētu ar šo licenci piešķirtās tiesības uz darbu. + +3.Pirmkoda pieejamība +Licenciārs var izplatīt darbu vai nu pirmkoda, vai izpildkoda formā. Ja darbs ir pieejams izpildkoda formā, kopā ar katru licenciāra izplatītu darba kopiju licenciārs papildus sniedz piekļuvi mašīnlasāmai darba pirmkoda kopijai vai aiz darbam pievienotās autortiesību zīmes norāda krātuvi, kurā pirmkods ir brīvi un bez maksas pieejams tik ilgi, kamēr licenciārs darbu turpina izplatīt vai darīt zināmu. + +4.Autortiesību ierobežojumi +Ar šo licenci netiek ierobežoti licenciāta ieguvumi, kas tam pienākas saskaņā ar jebkādu tādu izņēmumu vai ierobežojumu, kas ierobežo autortiesību subjektu izņēmuma tiesības attiecībā uz darbu, vai kas tam pienākas saskaņā ar šo tiesību izsmelšanu vai saskaņā ar citiem piemērojamiem ierobežojumiem. + +5.Licenciāta pienākumi +Iepriekš minēto tiesību piešķiršana uzliek licenciātam vairākus ierobežojumus un pienākumus. Minētie pienākumi ir šādi: + +Norādes tiesības: licenciāts nemaina nevienu autortiesību, patenta vai preču zīmes norādi, kā arī nevienu norādi uz šo licenci vai garantijas atrunu. Licenciātam ir jāpievieno šādu norāžu un šīs licences kopija ikvienai darba kopijai, ko tas izplata vai dara pieejamu. Licenciātam ir jānodrošina, ka uz katra atvasināta darba ir skaidri norādīts, ka darbs ir pārveidots, un pārveidošanas datums. + +Licences saglabāšana: ja licenciāts izplata vai dara zināmas oriģināldarbu vai atvasinātu darbu kopijas, tās izplata vai dara zināmas atbilstoši šīs licences vai tās vēlākas redakcijas noteikumiem, ja vien nav skaidri noteikts, ka oriģināldarbu izplata tikai saskaņā ar šo licences redakciju, piemēram, ar norādi “piemēro tikai EUPL 1.2. redakciju”. Licenciāts (kļūstot par licenciāru) nedrīkst piedāvāt vai uzspiest tādus papildu noteikumus vai nosacījumus attiecībā uz darbu vai atvasināto darbu, kas maina vai ierobežo licences noteikumus. + +Saderības atruna: ja licenciāts izplata vai dara zināmus atvasinātus darbus vai to kopijas, kas balstītas uz darbu un citu darbu ar saderīgu licenci, tos ir atļauts izplatīt vai darīt zināmus saskaņā ar minētās saderīgās licences noteikumiem. Šīs atrunas izpratnē “saderīga licence” nozīmē licences, kas ir uzskaitītas šīs licences pielikumā. Ja licenciāta pienākumi atbilstoši saderīgajai licencei ir pretrunā pienākumiem, kas izriet no šīs licences, noteicošie ir saderīgās licences noteikumi. + +Piekļuve pirmkodam: izplatot vai darot zināmas darba kopijas, licenciāts sagādā mašīnlasāmu pirmkoda kopiju vai norāda krātuvi, kurā pirmkods ir brīvi un bez maksas pieejams tik ilgi, kamēr licenciāts darbu turpina izplatīt vai darīt zināmu. + +Tiesiskā aizsardzība: šī licence nepiešķir atļauju lietot licenciāra tirdzniecības nosaukumus, preču zīmes, pakalpojumu zīmes vai licenciāra nosaukumus, izņemot gadījumus, kad tas ir nepieciešams pamatotam un ierastam lietojumam, kurā raksturo darba izcelsmi un atkārto autortiesību zīmes saturu. + +6.Autorības secība +Sākotnējais licenciārs garantē, ka tam pieder autortiesības uz oriģināldarbu vai tās ir licenciāram piešķirtas ar licenci un ka tam ir tiesības un pilnvaras izdot licenci. Katrs attīstītājs garantē, ka autortiesības uz tā veiktajiem darba pārveidojumiem tam pieder vai ir piešķirtas ar licenci un ka tam ir tiesības un pilnvaras izdot licenci. Katru reizi, kad jūs pieņemat licenci, sākotnējais licenciārs un nākamie attīstītāji jums atļauj izmantot viņu ieguldījumu darbā atbilstoši šīs licences noteikumiem. + +7.Garantijas atruna +Darba izstrāde turpinās, to nepārtraukti uzlabo daudzi attīstītāji. Tas nav pabeigts darbs, tāpēc tam var piemist trūkumi vai nepilnības, kas ir šāda veida izstrādes sastāvdaļa. Minētā iemesla dēļ ar šo licenci darbam sniedz piekļuvi tādam, “kāds tas ir”, un bez jebkādām garantijām attiecībā uz darbu, tostarp, bet ne tikai, bez garantijām par tā piemērotību pārdošanai, piemērotību noteiktam nolūkam, defektu vai kļūdu neesību, precizitāti, citu intelektuālā īpašuma tiesību nepārkāpšanu, kas nav šīs licences 6. pantā noteiktās autortiesības. Šī garantijas atruna ir būtiska licences sastāvdaļa un nosacījums, lai piešķirtu jebkādas tiesības uz darbu. + +8.Atbildības atruna +Izņemot tīšu nodarījumu vai fiziskām personām tieši nodarītus kaitējumus, licenciārs nekādā gadījumā neuzņemas atbildību ne par kādiem tiešiem vai netiešiem, mantiskiem vai morāliem jebkāda veida kaitējumiem, kas izriet no licences vai darba lietošanas, tostarp, bet ne tikai, kaitējumiem, kas saistīti ar nemateriālās vērtības mazināšanos, darbības pārtraukšanu, datora bojājumiem vai darbības traucējumiem, datu zudumu vai jebkādu komerciālu kaitējumu pat tad, ja licenciāram ir darīta zināma šādu kaitējumu iespējamība. Tomēr licenciārs ir atbildīgs saskaņā ar normatīvajiem aktiem par produktatbildību, ciktāl tie attiecas uz darbu. + +9.Papildu vienošanās +Izplatot darbu, jūs drīkstat noslēgt papildu vienošanos, nosakot pienākumus vai pakalpojumus, kas nav pretrunā šai licencei. Taču, uzņemoties pienākumus, jūs varat rīkoties vienīgi savā vārdā un uz savu atbildību, ne sākotnējā licenciāra vai kāda cita attīstītāja vārdā, un vienīgi tad, ja jūs apņematies atbrīvot visus attīstītājus no atbildības par jebkādām saistībām vai prasībām, kā arī atlīdzināt visus zaudējumus un aizstāvēt attīstītājus, ja pret kādu no tiem tiktu celta prasība jūsu garantiju vai papildu saistību dēļ. + +10.Licences pieņemšana +Šīs licences noteikumus var pieņemt, noklikšķinot uz ikonas “Piekrītu”, kas atrodas zem loga, kurā parādīts šīs licences teksts, vai apstiprinot piekrišanu citā līdzīgā veidā saskaņā ar piemērojamiem tiesību aktiem. Noklikšķinot uz ikonas, jūs apliecināt skaidru un neatsaucamu šīs licences un visu tās noteikumu un nosacījumu pieņemšanu. Tāpat jūs neatsaucami pieņemat šo licenci un visus tās noteikumus un nosacījumus, īstenojot jebkuras no tiesībām, kas jums piešķirtas ar šīs licences 2. pantu, piemēram, izmantojot darbu, radot atvasinātu darbu vai izplatot vai darot pieejamu darbu vai tā kopijas. + +11.Sabiedrības informēšana +Ja jūs darbu izplatāt vai darāt zināmu ar elektroniskiem sakaru līdzekļiem (piemēram, piedāvājot darbu lejupielādēt no attālināta datu avota), informācijas izplatīšanas līdzekļiem vai informācijas nesējiem (piemēram, tīmekļa vietnei), ir jāsniedz sabiedrībai vismaz tā informācija, kas ir noteikta piemērojamos tiesību aktos attiecībā uz licenciāru, licenci un to, kā licenciāts tai var piekļūt, kā to var apstiprināt, uzglabāt un reproducēt. + +12.Licences izbeigšana +Licence un ar to piešķirtās tiesības izbeidzas automātiski, līdzko licenciāts pārkāpj licences noteikumus. Šāda izbeigšana neizbeidz licences citām personām, kas ir saņēmušas darbu no licenciāta atbilstoši licencei, ja šīs personas pilnībā turpina rīkoties saskaņā ar licences noteikumiem. + +13.Dažādi +Neskarot 9. pantu, licence pilnībā atspoguļo pušu galīgo vienošanos attiecībā uz darbu. Ja kāds no licences noteikumiem nav spēkā vai nav izpildāms saskaņā ar piemērojamiem tiesību aktiem, tas neietekmē licences spēkā esību vai izpildāmību kopumā. Šādu noteikumu interpretē vai pārveido tā, kā ir nepieciešams, lai to padarītu spēkā esošu un izpildāmu. Eiropas Komisija var publicēt šīs licences redakcijas citās valodās vai jaunas šīs licences redakcijas, vai atjauninātas pielikuma redakcijas, ciktāl tas ir vajadzīgi un pamatoti, nemazinot ar šo licenci piešķirto tiesību apjomu. Katru jaunu licences redakciju publicē ar atšķirīgu redakcijas numuru. Eiropas Komisijas apstiprinātas šīs licences redakcijas visās valodās ir vienlīdzīgas. Puses var izvēlēties, kuras valodas redakciju izmantot. + +14.Jurisdikcija +Neskarot konkrētu starp pusēm noslēgtu vienošanos: +— jebkura tiesvedība, kas šīs licences interpretēšanas rezultātā rodas starp Eiropas Savienības iestādi, struktūru, biroju vai aģentūru kā licenciāru un jebkuru licenciātu, ir Eiropas Savienības Tiesas kompetencē, kā noteikts Līguma par Eiropas Savienības darbību 272. pantā, +— jebkura tiesvedība, kas rodas starp citām pusēm un šīs licences interpretēšanas rezultātā, ir tās valsts kompetentās tiesas ekskluzīvā piekritībā, kur licenciārs pastāvīgi uzturas vai kur ir tā galvenā uzņēmējdarbības vieta. + +15.Piemērojamie tiesību akti +Neskarot konkrētu starp pusēm noslēgtu vienošanos: +— šai licencei ir piemērojami tās Eiropas Savienības dalībvalsts tiesību akti, kur ir licenciāra mītnesvieta, kur tas pastāvīgi uzturas vai kur ir tā juridiskā adrese, +— ja licenciāra mītnesvieta, pastāvīgā dzīvesvieta vai juridiskā adrese neatrodas Eiropas Savienības dalībvalstī, šai licencei piemēro Beļģijas tiesību aktus. + +Papildinājums +“Saderīgas licences” saskaņā ar EUPL 5. pantu ir: +— GNU General Public License (GPL) v. 2, v. 3, +— GNU Affero General Public License (AGPL) v. 3, +— Open Software License (OSL) v. 2.1, v. 3.0, +— Eclipse Public License (EPL) v. 1.0, +— CeCILL v. 2.0, v. 2.1, +— Mozilla Public Licence (MPL) v. 2, +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3, +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) attiecībā uz darbiem, kas nav programmatūra, +— Eiropas Savienības sabiedriskā licence (EUPL), 1.1., 1.2. redakcija, +— Québec Free and Open-Source Licence – Reciprocity (LiLiQ-R) vai Strong Reciprocity (LiLiQ-R+). +Eiropas Komisija var atjaunināt šo pielikumu, lai iekļautu tajā iepriekš minēto licenču jaunākas redakcijas, nepieņemot jaunu EUPL redakciju, ja ar attiecīgajām licencēm tiek piešķirtas šīs licences 2. pantā noteiktās tiesības un netiek pieļauts, ka pirmkods, uz kuru attiecas licence, nonāk ekskluzīvā piederībā. +Lai šajā pielikumā varētu izdarīt citas izmaiņas vai papildinājumus, ir jāveido jauna EUPL redakcija. 19.5.2017. L 128/64 Eiropas Savienības Oficiālais Vēstnesis LV diff --git a/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 MT.txt b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 MT.txt new file mode 100644 index 0000000..7fe8c7a --- /dev/null +++ b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 MT.txt @@ -0,0 +1,98 @@ +LIĊENZJA PUBBLIKA TAL-UNJONI EWROPEA v. 1.2 +EUPL © L-Unjoni Ewropea 2007, 2016 +Din il-Liċenzja Pubblika tal-Unjoni Ewropea (l-“EUPL”) tapplika għax-Xogħol (kif definit hawn taħt) li jiġi pprovdut skont it-termini ta' din il-Liċenzja. Kwalunkwe użu tax-Xogħol, għajr kif awtorizzat permezz ta' din il-Liċenzja, huwa pprojbit (sakemm tali użu ma jkunx kopert bid-drittijiet tal-awtur tax-Xogħol). Ix-Xogħol huwa pprovdut skont ir-rekwiżiti ta' din il-Liċenzja meta l-Awtorità li toħroġ il-Liċenzja (kif definita hawn taħt) tkun ħarġet l-avviż li ġej immedjatament wara li jkun inħareġ l-avviż tad-drittijiet tal-awtur għax-Xogħol: + Mogħti liċenzja f'konformità mal-EUPL +jew tkun esprimiet b'xi mod jew ieħor ix-xewqa li tagħti liċenzja f'konformità mal-EUPL. + +1.Definizzjonijiet +F'din il-Liċenzja, it-termini li ġejjin għandhom dawn it-tifsiriet: +— “Il-Liċenzja”:din il-Liċenzja. +— “Ix-Xogħol Oriġinali”:is-softwer distribwit u/jew ikkomunikat mill-Awtorità li toħroġ il-Liċenzja skont din il- Liċenzja, disponibbli bħala Kodiċi tas-Sors u wkoll bħala Kodiċi Eżegwibbli, skont il-każ. +— Xogħlijiet Derivattivi:ix-xogħlijiet jew softwer li jistgħu jinħolqu mid-Detentur tal-Liċenzja, ibbażati fuq ix-Xogħol Oriġinali jew modifiki tiegħu. Din il-Liċenzja ma tiddefinix sa fejn biċċa xogħol għandha tkun modifikata jew dipendenti fuq ix-Xogħol Oriġinali sabiex tiġi kklassifikata bħala Xogħol Derivattiv; dan jiġi determinat bil-liġi dwar id-drittijiet tal-awtur applikabbli fil-pajjiż imsemmi fl-Artikolu 15. +— “Ix-Xogħol”:ix-Xogħol Oriġinali jew ix-Xogħlijiet Derivattivi tiegħu. +— “Il-Kodiċi tas-Sors”:l-għamla tax-Xogħol li tista' tinqara' mill-bniedem li hija l-aktar waħda konvenjenti għan-nies biex jistudjawha u jimmodifikawha. +— “Il-Kodiċi Eżegwibbli”:kwalunkwe kodiċi li ġie miġbur b'mod ġenerali u li huwa intenzjonat li jiġi interpretat minn kompjuter bħala programm. +— “L-Awtorità li toħroġ il-Liċenzja”:il-persuna naturali jew legali li tiddistribwixxi u/jew tikkomunika x-Xogħol permezz tal-Liċenzja. +— “Il-Kontributur(i)”:kwalunkwe persuna naturali jew legali li timmodifika x-Xogħol permezz tal-Liċenzja, jew inkella tikkontribwixxi għall-ħolqien ta' Xogħol Derivattiv. +— “Id-Detentur tal-Liċenzja” jew “Inti”:kwalunkwe persuna naturali jew legali li tuża x-Xogħol skont ir-rekwiżiti tal- Liċenzja. +— “Distribuzzjoni” jew “Komunikazzjoni”:kwalunkwe azzjoni ta' bejgħ, għoti, self, kiri, distribuzzjoni, komunikazzjoni, trażmissjoni, jew inkella b'modi oħra t-tqegħid għad-dispożizzjoni ta' kwalunkwe persuna oħra naturali jew legali ta' kopji tax-Xogħol, onlajn jew offlajn, jew l-għoti ta' aċċess għall-funzjonalitajiet essenzjali tax-Xogħol lil kwalunkwe persuna oħra naturali jew legali. + +2.L-ambitu tad-drittijiet mogħtija bil-Liċenzja +L-Awtorità li toħroġ il-Liċenzja b'dan Lilek tagħtik liċenzja li tista' tintuża madwar id-dinja kollha, ħielsa mid-dritt tal- awtur, mhux esklussiva, liċenzja subliċenzjabbli biex tagħmel dan li ġej, għat-tul ta' żmien stipulat tad-drittijiet tal-awtur mogħtija lix-Xogħol Oriġinali: +— tuża x-Xogħol fi kwalunkwe ċirkustanza u għal kull użu, +— tirriproduċi x-Xogħol, +— timmodifika x-Xogħol, u tagħmel Xogħlijiet Derivattivi bbażati fuqu, +— tikkomunika lill-pubbliku, inkluż id-dritt li tagħmel disponibbli jew turi lill-pubbliku x-Xogħol jew kopji tiegħu u li tħaddem ix-Xogħol pubblikament, skont ma jkun il-każ, +— tiddistribwixxi x-Xogħol jew kopji tiegħu, +— issellef u tikri x-Xogħol jew kopji tiegħu, +— tissubliċenzja d-drittijiet tal-awtur fix-Xogħol jew kopji tiegħu. +Dawk id-drittijiet jistgħu jiġu eżerċitati fi kwalunkwe midja, supporti u formati, kemm dawk magħrufin bħalissa kif ukoll dawk li jiġu skoperti aktar tard, sakemm tippermetti l-liġi applikabbli. Fil-pajjiżi fejn japplikaw id-drittijiet morali, l-Awtorità li toħroġ il-Liċenzja tirrinunzja d-dritt tagħha li teżerċita d-dritt morali sal-limitu li tippermetti l-liġi sabiex il-liċenzja tad-drittijiet ekonomiċi elenkati hawn fuq tkun effettiva. L-Awtorità li toħroġ il-Liċenzja tagħti lid-Detentur tal-Liċenzja drittijiet ta' użu, ħielsa mid-drittijiet tal-awtur u mhux esklussivi għal kwalunkwe brevett miżmum mill-Awtorità li toħroġ il-Liċenzja, sa fejn huwa meħtieġ sabiex jintużaw id- drittijiet mogħtija fuq ix-Xogħol permezz ta' din il-Liċenzja. + +3.Il-Komunikazzjoni tal-Kodiċi tas-Sors +L-Awtorità li toħroġ il-Liċenzja tista' tipprovdi x-Xogħol jew fl-għamla tal-Kodiċi tas-Sors, jew bħala Kodiċi Eżegwibbli. Jekk ix-Xogħol jiġi pprovdut bħala Kodiċi Eżegwibbli, l-Awtorità li toħroġ il-Liċenzja tipprovdi wkoll kopja li tista' tinqara minn magna tal-Kodiċi tas-Sors tax-Xogħol flimkien ma' kull kopja tax-Xogħol li l-Awtorità li toħroġ il-Liċenzja tiddistribwixxi jew tindika, f'avviż li jinħareġ wara l-avviż tad-drittijiet tal-awtur mehmuż max-Xogħol, repożitorju fejn il-Kodiċi tas-Sors ikun aċċessibbli faċilment u bil-libertà sakemm l-Awtorità li toħroġ il-Liċenzja tkompli tiddistribwixxi jew tikkomunika x-Xogħol. + +4.Limitazzjonijiet fuq id-drittijiet tal-awtur +Ma hemm xejn f'din il-Liċenzja li huwa intenzjonat li jċaħħad lid-Detentur tal-Liċenzja mill-benefiċċji ta' kwalunkwe eċċezzjoni jew limitazzjoni għad-drittijiet esklussivi tad-detenturi tad-drittijiet fix-Xogħol, jew mill-eżawriment ta' dawk id-drittijiet jew ta' limitazzjonijiet oħrajn applikabbli għalihom. + +5.Obbligi tad-Detentur tal-Liċenzja +L-għoti tad-drittijiet imsemmija hawn fuq huwa soġġett għal xi restrizzjonijiet u obbligi imposti fuq id-Detentur tal- Liċenzja. Dawk l-obbligi huma kif ġej: + +Dritt ta' attribuzzjoni: Id-Detentur tal-Liċenzja għandu jżomm sħaħ l-avviżi kollha tad-drittijiet tal-awtur, brevetti jew trademarks u l-avviżi kollha li jirreferu għal-Liċenzja u għar-rinunzja ta' garanziji. Id-Detentur tal-Liċenzja għandu jinkludi kopja ta' tali avviżi u kopja tal-Liċenzja ma' kull kopja tax-Xogħol li jiddistribwixxi jew jikkomunika. Id-Detentur tal-Liċenzja għandu jara li kull Xogħol Derivattiv jkollu avviżi prominenti li jistqarru li x-Xogħol ġie mmodifikat u d-data tal-modifika. + +Klawżola ta' copyleft: Jekk id-Detentur tal-Liċenzja jiddistribwixxi jew jikkomunika kopji tax-Xogħlijiet Oriġinali jew Xogħlijiet Derivattivi, din id-Distribuzzjoni jew Komunikazzjoni ssir skont it-termini ta' din il-Liċenzja jew ta' verżjoni sussegwenti ta' din il-Liċenzja, sakemm ix-Xogħol Oriġinali ma jkunx distribwit espressament biss skont din il-verżjoni tal-Liċenzja — pereżempju billi jikkomunika “EUPL v. 1.2 biss”. Id-Detentur tal-Liċenzja (li mbagħad isir l-Awtorità li toħroġ il-Liċenzja) ma jista' joffri jew jimponi l-ebda terminu jew kundizzjoni addizzjonali dwar ix-Xogħol jew Xogħol Derivattiv li jbiddlu jew jillimitaw it-termini tal-Liċenzja. + +Klawżola ta' kompatibbiltà: Jekk id-Detentur tal-Liċenzja Jiddistribwixxi jew Jikkomunika Xogħlijiet Derivattivi jew kopji tagħhom ibbażati kemm fuq ix-Xogħol Oriġinali kif ukoll fuq xogħol ieħor mogħti liċenzja permezz ta' Liċenzja Kompatibbli, din id-Distribuzzjoni jew Komunikazzjoni tista' issir skont it-termini ta' din il-Liċenzja Kompatibbli. Għall- finijiet ta' din il-Klawżola, “Liċenzja Kompatibbli” tirreferi għal-liċenzji elenkati fl-appendiċi mehmuża ma' din il-Liċenzja. Jekk l-obbligi tad-Detentur tal-Liċenzja skont il-Liċenzja Kompatibbli jmorru kontra l-obbligi tiegħu skont din il-Liċenzja, l-obbligi tal-Liċenzja Kompatibbli għandhom jipprevalu. + +Il-forniment tal-Kodiċi tas-Sors: Waqt id-distribuzzjoni jew komunikazzjoni ta' kopji tax-Xogħol, id-Detentur tal- Liċenzja jipprovdi kopja tal-Kodiċi tas-Sors li tinqara bil-magna jew inkella jindika repożitorju fejn dan is-Sors ikun disponibbli faċilment u mingħajr restrizzjonijiet sakemm id-Detentur tal-Liċenzja jkompli jiddistribwixxi jew jikkomunika x-Xogħol. + +Protezzjoni Legali: Din il-Liċenzja ma tagħtix permess għall-użu ta' ismijiet kummerċjali, trademarks, marki tas-servizz, jew ismijiet tal-Awtorità li toħroġ il-Liċenzja, minbarra kif meħtieġ għal użu raġonevoli u normali biex tiddeskrivi l- oriġini tax-Xogħol u biex tirriproduċi l-kontenut tal-avviż tad-drittijiet tal-awtur. + +6.Katina ta' Awturi +L-Awtorità oriġinali li toħroġ il-Liċenzja tiggarantixxi li d-dritt tal-awtur fuq ix-Xogħol Oriġinali mogħtija hawn taħt huwa l-proprjetà tagħha jew liċenzjat lilha u li għandha l-poter u l-awtorità li tagħti l-Liċenzja. Kull Kontributur jiggarantixxi li d-dritt tal-awtur fuq il-modifiki li jagħmel fix-Xogħol huwa l-proprjetà tiegħu jew li huma mogħtija lilu permezz ta' liċenzja u li għandu l-poter u l-awtorità li jagħti l-Liċenzja. Kull darba li Inti taċċetta l-Liċenzja, l-Awtorità oriġinali li tkun ħarġet il-Liċenzja u l-Kontributuri sussegwenti jagħtu liċenzja Lilek għall-kontributi tagħhom għax-Xogħol, skont it-termini ta' din il-Liċenzja. + +7.Rinunzja ta' Garanzija +Ix-Xogħol huwa xogħol li għadu għaddej, li jittejjeb kontinwament permezz ta' Kontributuri numerużi. Mhuwiex xogħol lest u għalhekk jista' jkollu difetti jew “bugs” inerenti f'dan it-tip ta' żvilupp. Għal din ir-raġuni, ix-Xogħol jiġi pprovdut permezz tal-Liċenzja fuq bażi “tale quale” u mingħajr garanziji ta' kwalunkwe tip dwar ix-Xogħol, inkluż mingħajr limitazzjonijiet, kummerċjabilità, adegwatezza għal xi skop partikolari, assenza ta' difetti jew żbalji, akkuratezza, nuqqas ta' vjolazzjoni ta' drittijiet ta' proprjetà intellettwali minbarra d-drittijiet tal-awtur kif stabbiliti bl-Artikolu 6 ta' din il-Liċenzja. Ir-rinunzja tal-garanzija hija parti essenzjali tal-Liċenzja u kundizzjoni għall-għoti ta' kwalunkwe dritt għax-Xogħol. + +8.Rinunzja ta' Responsabbiltà +Għajr fil-każijiet ta' kondotta ħażina volontarja jew ta' ħsarat ikkaġunati direttament lil persuni naturali, l-Awtorità li toħroġ il-Liċenzja fl-ebda każ ma tista' tinżamm responsabbli għal kwalunkwe ħsara diretta jew indiretta, materjali jew morali, ta' kwalunkwe xorta, li tirriżulta mil-Liċenzja jew mill-użu tax-Xogħol, fosthom mingħajr limitazzjoni, ħsarat għat-telf ta' avvjament, waqfien mix-xogħol, waqfien jew ħsara tal-kompjuter, telf ta' data jew ħsara kummerċjali, ukoll jekk l-Awtorità li toħroġ il-Liċenzja ġiet avżata dwar il-possibbiltà ta' tali ħsara. Madankollu, l-Awtorità li toħroġ il- Liċenzja tkun responsabbli skont il-liġijiet statutorji dwar ir-responsabbiltà tal-prodott, sakemm dawn il-liġijiet japplikaw għax-Xogħol. + +9.Ftehimiet Addizzjonali +Waqt id-distribuzzjoni tax-Xogħol, tista' tagħżel li tikkonkludi ftehim addizzjonali, li jiddefinixxi l-obbligi jew is-servizzi li huma konsistenti ma' din il-Liċenzja. Madankollu, jekk taċċetta tali obbligi, Inti tista' taġixxi biss f'ismek stess u bir- responsabbiltà tiegħek biss, mhux f'isem l-Awtorità oriġinali li tkun ħarġet il-Liċenzja jew kwalunkwe Kontributur ieħor, u dan biss jekk Inti taqbel li tikkumpensa, tiddefendi, u żżomm ħieles kull Kontributur għal kwalunkwe obbligazzjoni attwali, jew talba kontra tali Kontributur bil-fatt li Inti aċċettajt kwalunkwe tali garanzija jew responsabbiltà addizzjonali. + +10.Aċċettazzjoni tal-Liċenzja +Tista' taċċetta d-dispożizzjonijiet ta' din il-Liċenzja billi tikklikkja l-buttuna “Naqbel” taħt qiegħ it-tieqa li turi t-test ta' din il-Liċenzja, jew billi taqbel b'xi mod simili ieħor, skont ir-regoli tal-liġi applikabbli. Billi tikklikkja l-buttuna, Inti tkun qed tindika l-aċċettazzjoni ċara u irrevokabbli tiegħek għal din il-Liċenzja bit-termini u l-kundizzjonijiet kollha tagħha. Bl-istess mod, Inti taċċetta din il-Liċenzja u t-termini u l-kundizzjonijiet kollha tagħha b'mod irrevokabbli billi teżerċita kwalunkwe dritt mogħti Lilek bl-Artikolu 2 ta' din il-Liċenzja, bħall-użu tax-Xogħol, il-ħolqien minnek ta' Xogħol Derivattiv jew id-Distribuzzjoni jew Komunikazzjoni Tiegħek tax-Xogħol jew kopji tiegħu. + +11.Informazzjoni għall-pubbliku +Fil-każ ta' kwalunkwe Distribuzzjoni jew Komunikazzjoni tax-Xogħol permezz ta' komunikazzjoni elettronika Minnek (pereżempju, billi toffri li tniżżel ix-Xogħol minn post remot) il-mezzi ta' distribuzzjoni jew il-midja (pereżempju, sit web) għandhom tal-anqas jipprovdu għall-pubbliku t-tagħrif meħtieġ bil-liġi applikabbli dwar l-identifikazzjoni u l- indirizz tal-Awtorità li toħroġ il-Liċenzja, il-Liċenzja u l-mod kif tista' tkun aċċessibbli, konkluża, maħżuna u riprodotta mid-Detentur tal-Liċenzja. + +12.Terminazzjoni tal-Liċenzja +Il-Liċenzja u d-drittijiet mogħtija hawn jispiċċaw awtomatikament mal-ksur tal-kundizzjonijiet tal-Liċenzja mid-Detentur tal-Liċenzja. Terminazzjoni bħal din ma ttemmx il-liċenzji ta' kwalunkwe persuna li tkun irċeviet ix-Xogħol mid-Detentur tal-Liċenzja skont il-Liċenzja, sakemm tali persuni jibqgħu f'konformità sħiħa mal-Liċenzja. + +13.Mixxellanju +Mingħajr preġudizzju għall-Artikolu 9 hawn fuq, il-Liċenzja tirrappreżenta l-ftehim sħiħ bejn il-Partijiet rigward ix- Xogħol. Jekk kwalunkwe dispożizzjoni tal-Liċenzja ma tkunx valida jew infurzabbli bil-liġi applikabbli, dan ma jaffettwax il- validità jew l-infurzar tal-Liċenzja kollha kemm hi. Tali dispożizzjoni tinftiehem jew tkun riformata b'tali mod kif meħtieġ biex tkun valida u infurzabbli. Il-Kumissjoni Ewropea tista' tippubblika verżjonijiet b'lingwi oħra jew verżjoni ġdida ta' din il-Liċenzja jew verżjonijiet aġġornati tal-Appendiċi, sakemm dan ikun meħtieġ u raġonevoli, mingħajr ma tnaqqas l-ambitu tad-drittijiet mogħtija bil-Liċenzja. Verżjonijiet ġodda tal-Liċenzja jiġu ppublikati b'numru uniku tal-verżjoni. Il-verżjonijiet kollha ta' din il-Liċenzja bil-lingwi differenti, approvati mill-Kummissjoni Ewropea, għandhom valur identiku. Il-Partijiet jistgħu jutilizzaw il-verżjoni bil-lingwa tal-għażla tagħhom. + +14.Ġurisdizzjoni +Mingħajr preġudizzju għal ftehim speċifiku bejn il-partijiet, +— kwalunkwe tilwim li jirriżulta mill-interpretazzjoni ta' din il-Liċenzja li jista' jqum bejn l-istituzzjonijiet, korpi, uffiċċji jew aġenziji tal-Unjoni Ewropea, bħala l-Awtorità li toħroġ il-Liċenzja, u kwalunkwe Detentur tal-Liċenzja, ikun soġġett għall-ġuriżdizzjoni tal-Qorti tal-Ġustizzja tal-Unjoni Ewropea, kif stabbilit bl-Artikolu 272 tat-Trattat li jistabbilixxi l-Unjoni Ewropea. +— kwalunkwe tilwim li jista' jqum bejn Partijiet oħrajn, u li jirriżulta mill-interpretazzjoni ta' din il-Liċenzja, ikun soġġett għall-ġuriżdizzjoni esklussiva tal-qorti kompetenti fil-post ta' residenza tal-Awtorità tal-Liċenzja jew fejn huwa stabbilit in-negozju primarju tagħha. + +15.Liġi applikabbli +Mingħajr preġudizzju għal ftehim speċifiku bejn il-partijiet, +— Din il-Liċenzja għandha tkun irregolata mil-liġi tal-Istat Membru tal-Unjoni Ewropea fejn l-Awtorità li toħroġ il- Liċenzja hija residenti jew għandha l-uffiċċju rreġistrat tagħha, +— din il-liċenzja għandha tkun irregolata mil-Liġi Belġjana jekk minn joħroġ il-liċenzja ma jkollux sede, residenza jew uffiċċju rreġistrat fi Stat Membru tal-Unjoni Ewropea. + + +Appendiċi +“Liċenzji Kompatibbli” skont l-Artikolu 5 tal-EUPL huma: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) għal xogħlijiet għajr minn softwer +— European Union Public Licence (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) jew Strong Reciprocity (LiLiQ-R+). +Il-Kummissjoni Ewropea tista' taġġorna dan l-Appendiċi għal verżjonijiet sussegwenti tal-liċenzji hawn fuq imsemmija mingħajr ma tipproduċi verżjoni ġdida tal-EUPL, sakemm jiġu pprovduti d-drittijiet garantiti fl-Artikolu 2 ta' din il-Liċenzja u jiġi protett minn approprjazzjoni esklużiva l-Kodiċi Sors kopert. +Kull tibdil jew żieda ulterjuri għal dan l-Appendiċi jeħtieġ produzzjoni ta' verżjoni ġdida tal-EUPL. 19.5.2017 L 128/64 Il-Ġurnal Uffiċjali tal-Unjoni Ewropea MT diff --git a/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 NL.txt b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 NL.txt new file mode 100644 index 0000000..8f18371 --- /dev/null +++ b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 NL.txt @@ -0,0 +1,97 @@ +OPENBARE LICENTIE VAN DE EUROPESE UNIE v. 1.2. +EUPL © Europese Unie 2007, 2016 +Deze openbare licentie van de Europese Unie („EUPL”) is van toepassing op het werk (zoals hieronder gedefinieerd) dat onder de voorwaarden van deze licentie wordt verstrekt. Elk gebruik van het werk dat niet door deze licentie is toegestaan, is verboden (voor zover dit gebruik valt onder een recht van de houder van het auteursrecht op het werk). Het werk wordt verstrekt onder de voorwaarden van deze licentie wanneer de licentiegever (zoals hieronder gedefinieerd), direct volgend op de kennisgeving inzake het auteursrecht op het werk, de volgende kennisgeving opneemt: + In licentie gegeven krachtens de EUPL +of op een andere wijze zijn bereidheid te kennen heeft gegeven krachtens de EUPL in licentie te geven. + +1.Definities +In deze licentie wordt verstaan onder: +— „de licentie”:de onderhavige licentie; +— „het oorspronkelijke werk”:het werk dat of de software die door de licentiegever krachtens deze licentie wordt verspreid of medegedeeld, en dat/die beschikbaar is als broncode en, in voorkomend geval, ook als uitvoerbare code; +— „bewerkingen”:de werken of software die de licentiehouder kan creëren op grond van het oorspronkelijke werk of wijzigingen ervan. In deze licentie wordt niet gedefinieerd welke mate van wijziging of afhankelijkheid van het oorspronkelijke werk vereist is om een werk als een bewerking te kunnen aanmerken; dat wordt bepaald conform het auteursrecht dat van toepassing is in de in artikel 15 bedoelde staat; +— „het werk”:het oorspronkelijke werk of de bewerkingen ervan; +— „de broncode”:de voor mensen leesbare vorm van het werk, die het gemakkelijkste door mensen kan worden bestudeerd en gewijzigd; +— „de uitvoerbare code”:elke code die over het algemeen is gecompileerd en is bedoeld om door een computer als een programma te worden uitgevoerd; +— „de licentiegever”:de natuurlijke of rechtspersoon die het werk krachtens de licentie verspreidt of mededeelt; +— „bewerker(s)”:elke natuurlijke of rechtspersoon die het werk krachtens de licentie wijzigt of op een andere wijze bijdraagt tot de totstandkoming van een bewerking; +— „de licentiehouder” of „u”:elke natuurlijke of rechtspersoon die het werk onder de voorwaarden van de licentie gebruikt; — „verspreiding” of „mededeling”:het verkopen, geven, uitlenen, verhuren, verspreiden, mededelen, doorgeven, of op een andere wijze online of offline beschikbaar stellen van kopieën van het werk of het verlenen van toegang tot de essentiële functies ervan ten behoeve van andere natuurlijke of rechtspersonen. + +2.Draagwijdte van de uit hoofde van de licentie verleende rechten +De licentiegever verleent u hierbij een wereldwijde, royaltyvrije, niet-exclusieve, voor een sublicentie in aanmerking komende licentie, om voor de duur van het aan het oorspronkelijke werk verbonden auteursrecht, het volgende te doen: +— het werk in alle omstandigheden en voor ongeacht welk doel te gebruiken; +— het werk te verveelvoudigen; +— het werk te wijzigen en op grond van het werk bewerkingen te ontwikkelen; +— het werk aan het publiek mede te delen, waaronder het recht om het werk of kopieën ervan aan het publiek ter beschikking te stellen of te vertonen, en het werk, in voorkomend geval, in het openbaar uit te voeren; +— het werk of kopieën ervan te verspreiden; +— het werk of kopieën ervan uit te lenen en te verhuren; +— de rechten op het werk of op kopieën ervan in sublicentie te geven. +Deze rechten kunnen worden uitgeoefend met gebruikmaking van alle thans bekende of nog uit te vinden media, dragers en formaten, voor zover het toepasselijke recht dit toestaat. In de landen waar immateriële rechten van toepassing zijn, doet de licentiegever afstand van zijn recht op uitoefening van zijn immateriële rechten in de mate die door het toepasselijke recht wordt toegestaan teneinde een doeltreffende uitoefening van de bovenvermelde in licentie gegeven economische rechten mogelijk te maken. De licentiegever verleent de licentiehouder een royaltyvrij, niet-exclusief gebruiksrecht op alle octrooien van de licentiegever, voor zover dit noodzakelijk is om de uit hoofde van deze licentie verleende rechten op het werk te gebruiken. + +3.Mededeling van de broncode +De licentiegever kan het werk verstrekken in zijn broncode of als uitvoerbare code. Indien het werk als uitvoerbare code wordt verstrekt, verstrekt de licentiegever bij elke door hem verspreide kopie van het werk tevens een machinaal leesbare kopie van de broncode van het werk of geeft hij in een mededeling, volgende op de bij het werk gevoegde auteursrechtelijke kennisgeving, de plaats aan waar de broncode gemakkelijk en vrij toegankelijk is, zolang de licentiegever het werk blijft verspreiden of mededelen. + +4.Beperkingen van het auteursrecht +Geen enkele bepaling in deze licentie heeft ten doel de licentiehouder het recht te ontnemen een beroep te doen op een uitzondering op of een beperking van de exclusieve rechten van de rechthebbenden op het werk, of op de uitputting van die rechten of andere toepasselijke beperkingen daarvan. + +5.Verplichtingen van de licentiehouder +De verlening van de bovenvermelde rechten is onderworpen aan een aantal aan de licentiehouder opgelegde beperkingen en verplichtingen. Het gaat om de onderstaande verplichtingen. + +Attributierecht: de licentiehouder moet alle auteurs-, octrooi- of merkenrechtelijke kennisgevingen onverlet laten alsook alle kennisgevingen die naar de licentie en de afwijzing van garanties verwijzen. De licentiehouder moet een afschrift van deze kennisgevingen en een afschrift van de licentie bij elke kopie van het werk voegen die hij verspreidt of mededeelt. De licentiehouder moet in elke bewerking duidelijk aangeven dat het werk is gewijzigd, en eveneens de datum van wijziging vermelden. + +Copyleftclausule: wanneer de licentiehouder kopieën van het oorspronkelijke werk of bewerkingen verspreidt of mededeelt, geschiedt die verspreiding of mededeling onder de voorwaarden van deze licentie of van een latere versie van deze licentie, tenzij het oorspronkelijke werk uitdrukkelijk alleen onder deze versie van de licentie wordt verspreid — bijvoorbeeld door de mededeling „alleen EUPL v. 1.2”. De licentiehouder (die licentiegever wordt) kan met betrekking tot het werk of de bewerkingen geen aanvullende bepalingen of voorwaarden opleggen of stellen die de voorwaarden van de licentie wijzigen of beperken. + +Verenigbaarheidsclausule: wanneer de licentiehouder bewerkingen of kopieën ervan verspreidt of mededeelt die zijn gebaseerd op het werk en op een ander werk dat uit hoofde van een verenigbare licentie in licentie is gegeven, kan die verspreiding of mededeling geschieden onder de voorwaarden van deze verenigbare licentie. Voor de toepassing van deze clausule wordt onder „verenigbare licentie” verstaan, de licenties die in het aanhangsel bij deze licentie zijn opgesomd. Indien de verplichtingen van de licentiehouder uit hoofde van de verenigbare licentie in strijd zijn met diens verplichtingen uit hoofde van deze licentie, hebben de verplichtingen van de verenigbare licentie voorrang. + +Verstrekking van de broncode: bij de verspreiding of mededeling van kopieën van het werk verstrekt de licentiehouder een machinaal leesbare kopie van de broncode of geeft hij aan waar deze broncode gemakkelijk en vrij toegankelijk is, zolang de licentiehouder het werk blijft verspreiden of mededelen. + +Juridische bescherming: deze licentie verleent geen toestemming om handelsnamen, handelsmerken, dienstmerken of namen van de licentiegever te gebruiken, behalve wanneer dit op grond van een redelijk en normaal gebruik noodzakelijk is om de oorsprong van het werk te beschrijven en de inhoud van de auteursrechtelijke kennisgeving te herhalen. + +6.Auteursketen +De oorspronkelijke licentiegever garandeert dat hij houder is van het hierbij verleende auteursrecht op het oorspronkelijke werk dan wel dat dit hem in licentie is gegeven en dat hij de bevoegdheid heeft de licentie te verlenen. Elke bewerker garandeert dat hij houder is van het auteursrecht op de door hem aan het werk aangebrachte wijzigingen dan wel dat dit hem in licentie is gegeven en dat hij de bevoegdheid heeft de licentie te verlenen. Telkens wanneer u de licentie aanvaardt, verlenen de oorspronkelijke licentiegever en de opeenvolgende bewerkers u een licentie op hun bijdragen aan het werk onder de voorwaarden van deze licentie. + +7.Uitsluiting van garantie +Het werk is een werk in ontwikkeling, dat voortdurend door vele bewerkers wordt verbeterd. Het is een onvoltooid werk, dat bijgevolg nog tekortkomingen of programmeerfouten („bugs”) kan vertonen, die onlosmakelijk verbonden zijn met dit soort ontwikkeling. Om die reden wordt het werk op grond van de licentie verstrekt „zoals het is” en zonder enige garantie met betrekking tot het werk te geven, met inbegrip van, maar niet beperkt tot garanties met betrekking tot de verhandelbaarheid, de geschiktheid voor een specifiek doel, de afwezigheid van tekortkomingen of fouten, de nauwkeurigheid, de eerbiediging van andere intellectuele-eigendomsrechten dan het in artikel 6 van deze licentie bedoelde auteursrecht. Deze uitsluiting van garantie is een essentieel onderdeel van de licentie en een voorwaarde voor de verlening van rechten op het werk. + +8.Uitsluiting van aansprakelijkheid +Behoudens in het geval van een opzettelijke fout of directe schade aan natuurlijke personen, is de licentiegever in geen enkel geval aansprakelijk voor ongeacht welke directe of indirecte, materiële of immateriële schade die voortvloeit uit de licentie of het gebruik van het werk, met inbegrip van, maar niet beperkt tot schade als gevolg van het verlies van goodwill, verloren werkuren, een computerdefect of computerfout, het verlies van gegevens, of enige andere commerciële schade, zelfs indien de licentiegever werd gewezen op de mogelijkheid van dergelijke schade. De licentiegever is echter aansprakelijk op grond van de wetgeving inzake productaansprakelijkheid, voor zover deze wetgeving op het werk van toepassing is. + +9.Aanvullende overeenkomsten +Bij de verspreiding van het werk kunt u ervoor kiezen een aanvullende overeenkomst te sluiten, waarin de verplichtingen of diensten overeenkomstig deze licentie worden omschreven. Indien deze verplichtingen worden aanvaard, kunt u echter alleen in eigen naam en onder eigen verantwoordelijkheid handelen, en dus niet in naam van de oorspronkelijke licentiegever of een bewerker, en kunt u voorts alleen handelen indien u ermee instemt alle bewerkers schadeloos te stellen, te verdedigen of te vrijwaren met betrekking tot de aansprakelijkheid van of vorderingen tegen deze bewerkers op grond van het feit dat u een garantie of aanvullende aansprakelijkheid hebt aanvaard. + +10.Aanvaarding van de licentie +De bepalingen van deze licentie kunnen worden aanvaard door te klikken op het pictogram „Ik ga akkoord”, dat zich bevindt onderaan het venster waarin de tekst van deze licentie is weergegeven, of door overeenkomstig de toepasselijke wetsbepalingen op een soortgelijke wijze met de licentie in te stemmen. Door op dat pictogram te klikken geeft u aan dat u deze licentie en alle voorwaarden ervan ondubbelzinnig en onherroepelijk aanvaardt. Evenzo aanvaardt u onherroepelijk deze licentie en alle voorwaarden ervan door uitoefening van de rechten die u in artikel 2 van deze licentie zijn verleend, zoals het gebruik van het werk, het creëren door u van een bewerking of de verspreiding of mededeling door u van het werk of kopieën ervan. + +11.Voorlichting van het publiek +Indien u het werk verspreidt of mededeelt door middel van elektronische communicatiemiddelen (bijvoorbeeld door voor te stellen het werk op afstand te downloaden), moet het distributiekanaal of het medium (bijvoorbeeld een website) het publiek ten minste de gegevens verschaffen die door het toepasselijke recht zijn voorgeschreven met betrekking tot de licentiegever, de licentie en de wijze waarop deze kan worden geraadpleegd, gesloten, opgeslagen en gereproduceerd door de licentiehouder. + +12.Einde van de licentie +De licentie en de uit hoofde daarvan verleende rechten eindigen automatisch bij elke inbreuk door de licentiehouder op de voorwaarden van de licentie. Dit einde beëindigt niet de licenties van personen die het werk van de licentiehouder krachtens de licentie hebben ontvangen, mits deze personen zich volledig aan de licentie houden. + +13.Overige +Onverminderd artikel 9 vormt de licentie de gehele overeenkomst tussen de partijen met betrekking tot het werk. Indien een bepaling van de licentie volgens het toepasselijke recht ongeldig is of niet uitvoerbaar is, doet dit geen afbreuk aan de geldigheid of uitvoerbaarheid van de licentie in haar geheel. Deze bepaling dient zodanig te worden uitgelegd of gewijzigd dat zij geldig en uitvoerbaar wordt. De Europese Commissie kan, voor zover dit noodzakelijk en redelijk is, versies in andere talen of nieuwe versies van deze licentie of geactualiseerde versies van dit aanhangsel publiceren, zonder de draagwijdte van de uit hoofde van de licentie verleende rechten te beperken. Nieuwe versies van de licentie zullen worden gepubliceerd met een uniek versienummer. Alle door de Europese Commissie goedgekeurde taalversies van deze licentie hebben dezelfde waarde. De partijen kunnen zich beroepen op de taalversie van hun keuze. + +14.Bevoegd gerecht +Onverminderd specifieke overeenkomsten tussen de partijen, +— vallen alle geschillen tussen de instellingen, organen en instanties van de Europese Unie, als licentiegeefster, en een licentiehouder in verband met de uitlegging van deze licentie onder de bevoegdheid van het Hof van Justitie van de Europese Unie, conform artikel 272 van het Verdrag betreffende de werking van de Europese Unie, +— vallen alle geschillen tussen andere partijen in verband met de uitlegging van deze licentie onder de uitsluitende bevoegdheid van het bevoegde gerecht van de plaats waar de licentiegever is gevestigd of zijn voornaamste activiteit uitoefent. + +15.Toepasselijk recht +Onverminderd specifieke overeenkomsten tussen de partijen, +— wordt deze licentie beheerst door het recht van de lidstaat van de Europese Unie waar de licentiegever zijn statutaire zetel, verblijfplaats of hoofdkantoor heeft, +— wordt deze licentie beheerst door het Belgische recht indien de licentiegever geen statutaire zetel, verblijfplaats of hoofdkantoor heeft in een lidstaat van de Europese Unie. + + +Aanhangsel +„Verenigbare licenties” in de zin van artikel 5 EUPL zijn: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) voor andere werken dan software +— European Union Public Licence (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) of Strong Reciprocity (LiLiQ-R+). +De Europese Commissie kan dit aanhangsel actualiseren in geval van latere versies van de bovengenoemde licenties zonder dat er een nieuwe EUPL-versie wordt ontwikkeld, zolang die versies de uit hoofde van artikel 2 van deze licentie verleende rechten verlenen en ze de betrokken broncode beschermen tegen exclusieve toe-eigening. +Voor alle andere wijzigingen van of aanvullingen op dit aanhangsel is de ontwikkeling van een nieuwe EUPL-versie vereist. diff --git a/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 PL.txt b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 PL.txt new file mode 100644 index 0000000..4980f12 --- /dev/null +++ b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 PL.txt @@ -0,0 +1,98 @@ +LICENCJA PUBLICZNA UNII EUROPEJSKIEJ wersja 1.2 +EUPL © Unia Europejska 2007, 2016 +Niniejsza licencja publiczna Unii Europejskiej („EUPL”) stosowana jest w odniesieniu do utworu (w rozumieniu definicji poniżej) udostępnianego na warunkach niniejszej licencji. Każde wykorzystanie utworu inne niż dozwolone na mocy niniejszej licencji jest zakazane (w zakresie, w jakim takie wykorzystanie wchodzi w zakres prawa przysługującego posiadaczowi praw autorskich do utworu). Utwór jest udostępniany na warunkach niniejszej licencji, jeżeli licencjodawca (w rozumieniu definicji poniżej) umieści następującą wzmiankę bezpośrednio po informacji o prawach autorskich do utworu: + Na licencji EUPL +lub w jakikolwiek inny sposób wyrazi swój zamiar udzielenia licencji na podstawie EUPL. + +1.Definicje +W niniejszej licencji stosuje się następujące definicje: +— licencja:niniejsza licencja, +— utwór oryginalny:utwór lub oprogramowanie rozpowszechniane lub udostępniane przez licencjodawcę na podstawie niniejszej licencji, dostępne w postaci kodu źródłowego, a także – stosownie do przypadku – kodu wykonywalnego, +— utwory zależne:utwory lub oprogramowanie, które mogą zostać opracowane przez licencjobiorcę na podstawie utworu oryginalnego lub modyfikacji utworu oryginalnego. Niniejsza licencja nie określa zakresu modyfikacji lub zależności od utworu oryginalnego, wymaganego dla sklasyfikowania utworu jako utworu zależnego; zakres taki wynika z przepisów prawa autorskiego obowiązującego w państwie, o którym mowa w pkt 15, +— „utwór”:utwór oryginalny lub związane z nim utwory zależne, +— „kod źródłowy”:postać utworu czytelna dla człowieka, najdogodniejsza do analizy i modyfikacji, +— „kod wykonywalny”:każdy kod, który został zasadniczo skompilowany i który jako program przeznaczony jest do interpretacji przez komputer, +— „licencjodawca”:osoba fizyczna bądź prawna, która rozpowszechnia lub udostępnia utwór na podstawie licencji, +— „współautor (współautorzy)”:każda osoba fizyczna lub prawna, która modyfikuje utwór na podstawie licencji lub w inny sposób przyczynia się do stworzenia utworu zależnego, +— „licencjobiorca”:każda osoba fizyczna lub prawna, która w jakimkolwiek zakresie korzysta z utworu na warunkach licencji, +—„rozpowszechnianie” lub „udostępnianie”:każdy przypadek sprzedaży, przekazania, wypożyczenia, najmu, rozpowszechnienia, udostępnienia, nadania lub innego oddania kopii utworu do dyspozycji innej osobie fizycznej bądź prawnej lub zapewnienia im dostępu do jego istotnych funkcji w trybie on-line lub off-line. + +2.Zakres praw przyznawanych na mocy licencji +Licencjodawca niniejszym udziela licencjobiorcy obowiązującej na całym świecie, bezpłatnej, niewyłącznej licencji, obejmującej prawo do udzielania dalszych licencji, na wykonywanie następujących czynności przez okres obowiązywania praw autorskich do utworu oryginalnego: +— korzystanie z utworu we wszelkich okolicznościach i do wszelkich celów, +— zwielokrotnianie utworu, +— modyfikacja utworu oryginalnego oraz opracowywanie utworów zależnych na podstawie utworu, +— publiczne udostępnianie, w tym, stosownie do przypadku, prawo do publicznego udostępniania lub prezentacji utworu lub jego kopii oraz publicznego wykonywania utworu, +— rozpowszechnianie utworu lub jego kopii, +— wypożyczanie i najem utworu lub jego kopii, +— sublicencjonowanie praw do utworu lub jego kopii. +Powyższe prawa mogą być wykonywane bez względu na nośnik, rodzaj wsparcia i format, znany obecnie lub opracowany w przyszłości, w zakresie dozwolonym przepisami obowiązującego prawa. W państwach, w których przysługują autorskie prawa osobiste, licencjodawca zrzeka się przysługującego mu uprawnienia do wykonywania swoich autorskich praw osobistych w zakresie dozwolonym obowiązującymi przepisami w celu umożliwienia skutecznego udzielenia licencji w zakresie autorskich praw majątkowych wyszczególnionych powyżej. Licencjodawca niniejszym przyznaje licencjobiorcy bezpłatne, niewyłączne prawa do eksploatacji wszelkich patentów posiadanych przez licencjodawcę w zakresie niezbędnym do korzystania z praw do utworu przyznanych na mocy niniejszej licencji. + +3.Udostępnienie kodu źródłowego +Licencjodawca może udostępnić utwór w postaci kodu źródłowego lub kodu wykonywalnego. Jeżeli utwór udostępnia się w postaci kodu wykonywalnego, licencjodawca udostępnia jednocześnie kopię kodu źródłowego utworu w formie przeznaczonej do odczytu maszynowego wraz z każdą kopią utworu, którą licencjodawca rozpowszechnia, bądź wskazuje, w adnotacji następującej po informacji o prawach autorskich dołączonej do utworu, repozytorium, w którym łatwo i bezpłatnie dostępny jest kod źródłowy w czasie, w którym licencjodawca rozpowszechnia lub udostępnia utwór. + +4.Ograniczenia praw autorskich +Żadne z postanowień niniejszej licencji nie ma na celu pozbawienia licencjobiorcy korzyści wynikających z wszelkich wyjątków lub ograniczeń w stosunku do wyłącznych praw przysługujących właścicielom praw do utworu, ani korzyści płynących z faktu wyczerpania powyższych praw lub innych stosownych ograniczeń tych praw. + +5.Obowiązki licencjobiorcy +Przyznanie praw, o których mowa powyżej, podlega określonym ograniczeniom i obowiązkom nałożonym na licencjobiorcę. Obowiązki te obejmują: + +Prawo do autorstwa utworu: Licencjobiorca zobowiązuje się pozostawić w niezmienionej formie wszelkie informacje o prawach autorskich, patentach lub znakach towarowych oraz wszelkie adnotacje dotyczące licencji i wyłączenia gwarancji. Licencjobiorca zobowiązany jest dołączać kopię takich informacji i adnotacji oraz kopię licencji do każdej kopii utworu przez niego rozpowszechnianej lub udostępnianej. Licencjobiorca musi zadbać o to, aby wszelkie utwory zależne opatrzone zostały w widocznym miejscu informacją, że utwór uległ modyfikacji, wraz z datą takiej modyfikacji. + +Klauzula zakazu wprowadzania zmian i ograniczeń do licencji („copyleft”): Jeżeli licencjobiorca rozpowszechnia lub udostępnia kopie utworów oryginalnych lub utworów zależnych, takie rozpowszechnianie lub udostępnianie musi odbywać się na warunkach niniejszej licencji lub późniejszej wersji niniejszej licencji, chyba że rozpowszechnianie utworu oryginalnego wyraźnie odbywa się wyłącznie na podstawie niniejszej wersji licencji – na przykład poprzez dodanie zastrzeżenia „wyłącznie na podstawie EUPL wersja 1.2”. Licencjobiorca (działając w charakterze licencjodawcy) nie może oferować ani nakładać na utwór ani na utwór zależny żadnych dodatkowych postanowień ani warunków zmieniających bądź ograniczających warunki licencji. + +Klauzula zgodności: Jeżeli licencjobiorca rozpowszechnia lub udostępnia utwory zależne lub ich kopie opracowane na podstawie utworu i innego utworu licencjonowanego na mocy zgodnej licencji, takie rozpowszechnianie lub udostępnianie może odbywać się na warunkach wspomnianej zgodnej licencji. Do celów niniejszej klauzuli termin „zgodna licencja” obejmuje licencje wymienione w załączniku do niniejszej licencji. Jeżeli obowiązki licencjobiorcy wynikające ze zgodnej licencji są sprzeczne z jego obowiązkami wynikającymi z niniejszej licencji, obowiązki określone w zgodnej licencji mają charakter nadrzędny. + +Udostępnienie kodu źródłowego: Rozpowszechniając lub udostępniając kopie utworu, licencjobiorca udostępnia przeznaczoną do odczytu maszynowego kopię kodu źródłowego lub wskazuje repozytorium, w którym ten kod będzie łatwo i bezpłatnie dostępny w czasie, w którym licencjobiorca rozpowszechnia lub udostępnia utwór. + +Ochrona prawna: Niniejsza licencja nie upoważnia do korzystania z nazw handlowych, znaków towarowych, znaków usługowych ani nazw licencjodawcy, z wyjątkiem przypadków uzasadnionego i zwyczajowo przyjętego opisu pochodzenia utworu i powielania treści informacji o prawach autorskich. + +6.Ciąg autorstwa +Pierwotny licencjodawca gwarantuje, że prawa autorskie do utworu oryginalnego przyznane na mocy niniejszej licencji stanowią jego własność lub że posiada je na mocy stosownej licencji oraz że jest uprawniony i upoważniony do udzielania licencji. Każdy współautor gwarantuje, że prawa autorskie do modyfikacji, jakie wprowadza do utworu, stanowią jego własność lub że posiada je na mocy stosownej licencji oraz że jest uprawniony i upoważniony do udzielania licencji. Każdorazowo gdy licencjobiorca akceptuje licencję, pierwotny licencjodawca i późniejsi współautorzy udzielają licencjobiorcy licencji w stosunku do ich wkładu w utwór na warunkach niniejszej licencji. + +7.Wyłączenie gwarancji +Utwór ma charakter utworu nieukończonego, wciąż udoskonalanego przez wielu współautorów. Nie stanowi on utworu gotowego i dlatego może posiadać wady lub błędy właściwe dla tej formy opracowywania utworów. Z powyższych względów utwór przekazuje się na mocy licencji w postaci, w jakiej jest udostępniany, i bez jakichkolwiek gwarancji dotyczących utworu, w tym między innymi bez gwarancji przydatności handlowej, gwarancji przydatności do określonego celu, gwarancji braku wad lub błędów, gwarancji dokładności, gwarancji braku naruszenia praw własności intelektualnej innych niż prawa autorskie, o których mowa w pkt 6 niniejszej licencji. Niniejsze wyłączenie gwarancji stanowi istotny element licencji oraz warunek przyznania jakichkolwiek praw do utworu. + +8.Wyłączenie odpowiedzialności +Z zastrzeżeniem przypadków działań umyślnych na szkodę osób fizycznych lub szkód wyrządzonych bezpośrednio osobom fizycznym, licencjodawca w żadnym wypadku nie ponosi odpowiedzialności za bezpośrednie lub pośrednie, majątkowe lub osobiste szkody dowolnego rodzaju powstałe w związku z licencją lub eksploatacją utworu, w tym między innymi za szkody związane z utratą wartości firmy, przerwami w pracy, awarią bądź zakłóceniami pracy komputera, utratą danych ani za wszelkie inne szkody gospodarcze, nawet jeżeli licencjodawca został poinformowany o możliwości ich wystąpienia. Licencjodawca ponosi jednak odpowiedzialność zgodnie z ustawowymi przepisami regulującymi kwestie odpowiedzialności za produkt w zakresie, w jakim takie przepisy mają zastosowanie do utworu. + +9.Dodatkowe umowy +Rozpowszechniając utwór, licencjobiorca może postanowić o zawarciu dodatkowej umowy określającej zobowiązania lub świadczenia zgodne z niniejszą licencją. Przyjmując takie zobowiązania, licencjobiorca może występować jedynie we własnym imieniu i na własną odpowiedzialność, a nie w imieniu pierwotnego licencjodawcy ani żadnego innego współautora, oraz tylko pod warunkiem że licencjobiorca zobowiąże się względem każdego współautora do wypłacenia mu rekompensaty, jego obrony i zwolnienia go z odpowiedzialności, jeśli w związku z faktem, że licencjobiorca przyjął dodatkowe zobowiązania lub gwarancje, po stronie takiego współautora powstanie odpowiedzialność lub wysunięte zostaną wobec niego roszczenia. + +10.Akceptacja licencji +Postanowienia niniejszej licencji mogą zostać zaakceptowane poprzez kliknięcie ikony „Wyrażam zgodę” umieszczonej na dole okna, w którym wyświetlono pełną treść niniejszej licencji, lub poprzez potwierdzenie własnej zgody w jakikolwiek inny podobny sposób zgodny z przepisami obowiązującego prawa. Kliknięcie takiej ikony jest równoznaczne z wyraźną i nieodwołalną akceptacją niniejszej licencji oraz wszystkich jej warunków. Analogicznie, nieodwołalną akceptację przez licencjobiorcę niniejszej licencji i wszystkich jej warunków stanowi także wykonanie jakiegokolwiek prawa przyznanego licencjobiorcy na mocy pkt 2 niniejszej licencji, takie jak wykorzystanie utworu, opracowanie przez licencjobiorcę utworu zależnego bądź rozpowszechnienie lub udostępnienie przez licencjobiorcę utworu lub jego kopii. + +11.Podawanie informacji do publicznej wiadomości +W przypadku rozpowszechniania lub udostępniania przez licencjobiorcę utworu drogą komunikacji elektronicznej (na przykład poprzez oferowanie utworu do pobrania z lokalizacji zdalnej), w obrębie kanału rozpowszechniania lub nośnika (na przykład witryny internetowej) należy przynajmniej podać do wiadomości publicznej informacje wymagane przepisami obowiązującego prawa dotyczące licencjodawcy, licencji oraz sposobu, w jaki może zostać udostępniona, zawarta, przechowywana i zwielokrotniana przez licencjobiorcę. + +12.Wygaśnięcie licencji +Licencja i prawa przyznane na jej mocy wygasają automatycznie z chwilą naruszenia przez licencjobiorcę warunków licencji. Takie wygaśnięcie nie skutkuje jednak wygaśnięciem licencji przysługującej którejkolwiek z osób, które otrzymały utwór od licencjobiorcy na mocy licencji, pod warunkiem że takie osoby nadal przestrzegają w pełni postanowień licencji. + +13.Postanowienia różne +Nie naruszając postanowień pkt 9, licencja stanowi całość porozumienia między stronami w odniesieniu do utworu. Jeżeli jakiekolwiek postanowienie licencji okaże się nieważne lub niewykonalne na gruncie obowiązującego prawa, pozostaje to bez wpływu na ważność lub wykonalność licencji jako całości. Takie nieważne lub niewykonalne postanowienie należy interpretować lub dostosować w taki sposób, by zapewnić jego ważność i wykonalność. Komisja Europejska może publikować inne wersje językowe lub nowe wersje niniejszej licencji bądź zaktualizowane wersje załącznika, jeżeli jest to konieczne i uzasadnione, bez zawężania zakresu praw przyznanych na mocy licencji. Nowe wersje licencji publikuje się pod niepowtarzalnym numerem wersji. Wszystkie zatwierdzone przez Komisję Europejską wersje językowe niniejszej licencji mają taką samą wartość. Strony mogą korzystać z dowolnej wybranej przez siebie wersji językowej. + +14.Jurysdykcja +Bez uszczerbku dla szczegółowych uzgodnień między stronami, +— wszelkie spory sądowe związane z interpretacją niniejszej licencji, wynikłe między instytucjami, organami, urzędami lub agencjami Unii Europejskiej jako licencjodawcą a dowolnym licencjobiorcą, podlegają jurysdykcji Trybunału Sprawiedliwości Unii Europejskiej, zgodnie z postanowieniami art. 272 Traktatu o funkcjonowaniu Unii Europejskiej, +— wszelkie spory sądowe związane z interpretacją niniejszej licencji, wynikłe między innymi stronami, podlegają wyłącznej jurysdykcji sądu właściwego miejscowo dla miejsca zamieszkania licencjodawcy bądź jego głównego miejsca prowadzenia działalności gospodarczej. + +15.Prawo właściwe +Bez uszczerbku dla szczegółowych uzgodnień między stronami, +— prawem właściwym dla wykonania niniejszej licencji jest prawo państwa członkowskiego Unii Europejskiej, w którym zamieszkuje lub posiada swą siedzibę (statutową) licencjodawca, +— prawem właściwym dla wykonania niniejszej licencji jest prawo belgijskie, jeżeli licencjodawca nie ma miejsca zamieszkania lub siedziby (statutowej) na terenie państwa członkowskiego Unii Europejskiej. + + +Załącznik +„Zgodne licencje” w rozumieniu pkt 5 EUPL to: +— GNU General Public License (GPL) wersja 2, wersja 3 +— GNU Affero General Public License (AGPL) wersja 3 +— Open Software License (OSL) wersja 2.1, wersja 3.0 +— Eclipse Public License (EPL) wersja 1.0 +— CeCILL wersja 2.0, wersja 2.1 +— Mozilla Public Licence (MPL) wersja 2 +— GNU Lesser General Public Licence (LGPL) wersja 2.1, wersja 3 +— Creative Commons Attribution-ShareAlike wersja 3.0 Unported (CC BY-SA 3.0) w odniesieniu do utworów innych niż oprogramowanie +— licencja publiczna Unii Europejskiej (EUPL) wersja 1.1, wersja 1.2 +— Québec Free and Open-Source Licence – Reciprocity (LiLiQ-R) lub Strong Reciprocity (LiLiQ-R+). +Komisja Europejska może zaktualizować ten załącznik, aby uwzględnić w nim późniejsze wersje wyżej wymienionych licencji bez sporządzania nowej wersji EUPL, o ile te nowe wersje przyznają prawa przewidziane w pkt 2 niniejszej licencji oraz chronią kod źródłowy wchodzący w jej zakres przed wyłącznym przywłaszczeniem. +Wszelkie inne zmiany lub uzupełnienia niniejszego załącznika wymagają sporządzenia nowej wersji EUPL. 19.5.2017 L 128/64 Dziennik Urzędowy Unii Europejskiej PL diff --git a/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 PT.txt b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 PT.txt new file mode 100644 index 0000000..5c7e3c3 --- /dev/null +++ b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 PT.txt @@ -0,0 +1,97 @@ +LICENÇA PÚBLICA DA UNIÃO EUROPEIA v. 1.2 +EUPL © União Europeia 2007, 2016 +A presente licença pública da União Europeia («EUPL») aplica-se a qualquer obra (como definido abaixo) que seja fornecido nos termos da presente licença. É proibida qualquer utilização da obra diferente da autorizada nos termos da presente licença (na medida em que tal utilização esteja abrangida por um direito do titular dos direitos de autor da obra). A obra é fornecida nos termos da presente licença caso o licenciante (como definido abaixo) tenha colocado o seguinte aviso imediatamente após a informação sobre os direitos de autor respeitantes à obra: + Licenciada nos termos da EUPL +ou tenha expresso por qualquer outro meio a sua vontade de licenciar a obra nos termos da EUPL. + +1.Definições +Na presente licença, entende-se por: +— Licença:a presente licença. +— Obra original:a obra ou software distribuídos ou comunicados pelo licenciante nos termos da presente licença, disponível como código-fonte e também como código executável, consoante o caso. +— Obras derivadas:obras ou software que podem ser criados pelo licenciado com base na obra original ou mediante modificações nela introduzidas. A presente licença não define o grau de modificação ou de dependência em relação à obra original necessário para classificar uma obra como obra derivada; esse grau é determinado pela legislação relativa aos direitos de autor aplicável no país mencionado no ponto 15. +— Obra:a obra original ou as obras dela derivadas. +— Código-fonte:o formato legível por pessoas da obra que é o mais adequado para ser examinado e modificado. +— Código executável:qualquer código que, em geral, foi compilado e se destina a ser interpretado por um computador como um programa. +— Licenciante:pessoa singular ou coletiva que distribui ou comunica a obra nos termos da licença. +— Contribuidor(es):pessoa singular ou coletiva que modifica a obra abrangida pela licença ou contribui de outro modo para a criação de uma obra derivada. +— Licenciado:pessoa singular ou coletiva que utiliza a obra nos termos da licença. — Distribuição ou comunicação:ato de venda, doação, comodato, locação, distribuição, comunicação, transmissão ou qualquer outra forma de disponibilização, em linha ou fora de linha, de cópias da obra ou do acesso às suas funcionalidades essenciais a qualquer outra pessoa singular ou coletiva. + +2.Âmbito dos direitos concedidos pela licença +O licenciante concede ao licenciado uma licença mundial, gratuita, não exclusiva e sublicenciável, pelo período de duração dos direitos de autor sobre a obra original, para praticar os seguintes atos: +— utilizar a obra em quaisquer circunstâncias e para quaisquer fins, +— reproduzir a obra, +— modificar a obra e fazer obras derivadas baseadas na obra, +— comunicar a obra ao público, nomeadamente disponibilizando ou apresentando a obra ou cópias da obra ao público ou executando-a publicamente, consoante o caso, +— distribuir a obra ou cópias desta, +— emprestar e locar a obra ou cópias desta, +— sublicenciar os direitos sobre a obra ou cópias desta. +Estes direitos podem ser exercidos através de quaisquer meios, suportes ou formatos, conhecidos ou que venham a ser inventados, na medida em que tal seja permitido nos termos da legislação aplicável. Nos países em que sejam reconhecidos direitos morais, o licenciante renuncia aos seus direitos morais na medida em que a lei o permita, a fim de tornar efetiva a licença dos direitos patrimoniais acima enumerados. O licenciante concede ao licenciado, a título gratuito e não exclusivo, os direitos de utilização de quaisquer patentes de que o licenciante seja titular, na medida do necessário para a utilização dos direitos concedidos sobre a obra pela presente licença. + +3.Comunicação do código-fonte +O licenciante pode fornecer a obra como código-fonte ou como código executável. Caso a obra seja fornecida como código executável, o licenciante fornece ainda uma cópia legível por computador do código-fonte da obra, juntamente com cada cópia da obra que o licenciante distribui, ou indica, em aviso colocado a seguir à informação sobre os direitos de autor que acompanha a obra, um repositório onde o código-fonte esteja acessível fácil e gratuitamente enquanto o licenciante continuar a distribuir ou comunicar a obra. + +4.Limitação dos direitos de autor +A presente licença não pretende, de modo algum, privar o licenciado dos benefícios decorrentes de qualquer exceção ou limitação dos direitos exclusivos dos titulares dos direitos sobre a obra, da caducidade desses direitos ou de outras limitações aplicáveis. + +5.Obrigações previstas na licença +A concessão dos direitos acima mencionados está sujeita a algumas restrições e obrigações impostas ao licenciado. As obrigações são as seguintes: + +Direito de atribuição: o licenciado deve manter intactos todos os avisos sobre direitos de autor, patentes ou marcas, bem como todos os avisos que se referem à licença e à exclusão de garantia. O licenciado deve juntar uma cópia destes avisos e uma cópia da licença a cada cópia da obra que distribua ou comunique. O licenciado assegura que qualquer obra derivada contenha um aviso bem visível da alteração da obra e da data dessa alteração. + +Cláusula Copyleft: caso o licenciado distribua ou comunique cópias da obra original ou de obras derivadas, tal distribuição ou comunicação é feita nos termos da presente licença ou de uma versão posterior da presente licença, a menos que a obra original seja expressa e exclusivamente distribuída nos termos da presente versão da licença — por exemplo, através da comunicação «Distribuída apenas nos termos da licença EUPL v. 1.2». O licenciado (que se torna licenciante) não pode oferecer ou impor à obra ou à obra derivada termos ou condições suplementares que alterem ou restrinjam os termos da licença. + +Cláusula de compatibilidade: caso o licenciado distribua ou comunique obras derivadas ou cópias destas baseadas na obra e noutras obras licenciadas nos termos de uma licença compatível, tal distribuição ou comunicação pode ser feita nos termos dessa licença compatível. No âmbito da presente cláusula, entende-se por «licença compatível» uma licença enumerada no apêndice anexo à presente licença. Caso as obrigações do licenciado nos termos da licença compatível colidam com as suas obrigações nos termos da presente licença, prevalecem as obrigações da licença compatível. + +Fornecimento do código-fonte: ao distribuir ou comunicar cópias da obra, o licenciado fornece uma cópia legível por computador do código-fonte ou indica um repositório onde este código esteja disponível fácil e gratuitamente enquanto o licenciado continuar a distribuir ou comunicar a obra. + +Proteção jurídica: a presente licença não permite a utilização de firmas, marcas ou nomes do licenciante, exceto na medida do necessário para uma utilização razoável e conforme com as práticas habituais na descrição da origem da obra e na reprodução do teor do aviso sobre os direitos de autor. + +6.Cadeia de criação +O licenciante original garante que os direitos de autor sobre a obra original concedidos pela presente licença lhe pertencem ou lhe foram licenciados e que tem legitimidade para conceder a licença. Cada contribuidor garante que os direitos de autor sobre as alterações que introduziu na obra lhe pertencem ou lhe foram licenciados e que tem legitimidade para conceder a licença. Sempre que o licenciado aceite a licença, o licenciante original e os contribuidores subsequentes concedem ao licenciado uma licença respeitante aos seus contributos para a obra nos termos da presente licença. + +7.Exclusão de garantia +A obra é um trabalho em curso, continuamente melhorado por numerosos contribuidores. Não é um trabalho acabado, pelo que pode conter defeitos ou erros inerentes a este tipo de trabalho de criação. Por essa razão, a obra é fornecida «tal e qual» nos termos da licença e sem quaisquer garantias, como, entre outras, as respeitantes à comercialização, adequação a um determinado fim, ausência de defeitos ou erros, fiabilidade e não--violação dos direitos de propriedade intelectual distintos dos direitos de autor a que se refere o ponto 6 da presente licença. A presente exclusão de garantia constitui um elemento essencial da licença e uma condição para a concessão de quaisquer direitos sobre a obra. + +8.Exclusão de responsabilidade +Excetuados os casos de conduta dolosa ou de danos diretamente causados a pessoas singulares, o licenciante não é, em caso algum, responsável por quaisquer danos diretos ou indiretos, materiais ou morais, de qualquer natureza, decorrentes da licença ou da utilização da obra, como, por exemplo, danos por perda de clientela, paragem do trabalho, falhas ou anomalias no funcionamento do equipamento informático, perda de dados ou qualquer dano comercial, ainda que o licenciante tenha sido avisado da possibilidade da ocorrência de tais danos. No entanto, o licenciante é responsável nos termos da legislação relativa à responsabilidade por produtos na medida em que tal legislação seja aplicável à obra. + +9.Acordos suplementares +Ao distribuir a obra, o licenciado (enquanto licenciante) pode concluir um acordo suplementar, definindo obrigações ou serviços compatíveis com a presente licença. No entanto, ao aceitar essas obrigações, o licenciado (enquanto licenciante) age apenas em seu nome e por sua exclusiva responsabilidade e não em nome do licenciante original ou de qualquer outro contribuidor e apenas no caso de o licenciado (enquanto licenciante) aceitar indemnizar e defender estes contribuidores, exonerando-os de qualquer responsabilidade caso venham a ser acusados como consequência de o licenciado (enquanto licenciante) ter aceitado obrigações de garantia ou de responsabilidade suplementar. + +10.Aceitação da licença +Para aceitar o disposto na presente licença, o licenciado pode clicar no ícone «Aceito», situado na parte inferior de uma janela que contém o texto da presente licença, ou exprimir o seu consentimento por qualquer outra forma similar, em conformidade com a legislação aplicável. Ao clicar no referido ícone, o licenciado aceita de forma clara e irrevogável a presente licença e os seus termos e condições. Do mesmo modo, o licenciado aceita irrevogavelmente a presente licença, bem como os seus termos e condições, ao exercer quaisquer direitos concedidos pelo ponto 2 da presente licença, nomeadamente a utilização da obra, a criação pelo licenciado de uma obra derivada ou a distribuição ou comunicação pelo licenciado da obra ou de cópias desta. + +11.Informação ao público +Caso o licenciado distribua ou comunique a obra através de meios de comunicação eletrónicos (por exemplo, oferecendo a possibilidade de a telecarregar), o canal ou meio de distribuição (por exemplo, um sítio web) deve fornecer ao público, no mínimo, a informação exigida pela legislação aplicável no que respeita ao licenciante, à licença e ao modo como pode ser obtida, concluída, armazenada e reproduzida pelo licenciado. + +12.Cessação da licença +A licença e os direitos por ela concedidos cessam automaticamente caso o licenciado não respeite o disposto na licença. Esta cessação não acarreta a cessação das licenças das pessoas que tenham recebido a obra do licenciado nos termos da licença, desde que essas pessoas continuem a respeitar plenamente o disposto na licença. + +13.Diversos +Sem prejuízo do disposto no ponto 9, a licença representa o acordo integral entre as Partes no que respeita à obra. Caso uma disposição da licença seja inválida ou ineficaz por força da legislação aplicável, tal não afeta a validade ou a eficácia da licença no seu todo. Tal disposição será interpretada ou reformulada na medida do necessário para a tornar válida e eficaz. A Comissão Europeia pode publicar outras versões linguísticas, novas versões da presente licença ou versões atualizadas do apêndice, na medida em que tal seja necessário e razoável, sem reduzir o âmbito de aplicação dos direitos concedidos pela licença. As novas versões da licença serão publicadas com um número de versão único. Todas as versões linguísticas da presente licença, aprovadas pela Comissão Europeia, têm idêntico valor. As Partes podem utilizar a versão linguística da sua preferência. + +14.Jurisdição +Sem prejuízo de um acordo específico entre as Partes, +— o Tribunal de Justiça da União Europeia tem competência exclusiva para dirimir qualquer litígio resultante da interpretação da presente licença entre as instituições, órgãos, organismos ou agências da União Europeia enquanto licenciantes, e qualquer licenciado, em conformidade com o disposto no artigo 272.o do Tratado sobre o Funcionamento da União Europeia, +— o tribunal da residência do licenciante ou do local onde este exerce a sua atividade principal tem competência exclusiva para dirimir qualquer litígio entre outras Partes resultante da interpretação da presente licença. + +15.Direito aplicável +Sem prejuízo de um acordo específico entre as Partes, +— a presente licença é regida pelo direito do Estado-Membro da União Europeia onde o licenciante tenha a sua sede, domicílio ou estabelecimento, +— a presente licença é regida pelo direito belga, caso o licenciante não tenha a sua sede, domicílio ou estabelecimento num Estado-Membro da União Europeia. + + +Apêndice +As «licenças compatíveis» a que se refere o ponto 5 da EUPL são: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) para obras que não sejam software +— European Union Public Licence (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+). +A Comissão pode atualizar o presente apêndice a fim de incluir novas versões das licenças supra, sem a produção de uma nova versão da EUPL, desde que tais versões concedam os direitos conferidos pelo ponto 2 da presente licença e protejam o código-fonte abrangido de apropriação exclusiva. +Todas as outras alterações ou aditamentos ao presente apêndice exigem a produção de uma nova versão da EUPL. diff --git a/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 RO.txt b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 RO.txt new file mode 100644 index 0000000..4471d50 --- /dev/null +++ b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 RO.txt @@ -0,0 +1,98 @@ +LICENȚA PUBLICĂ A UNIUNII EUROPENE V. 1.2 +EUPL© Uniunea Europeană 2007, 2016 +Prezenta licență publică a Uniunii Europene („EUPL”) se aplică produselor (astfel cum sunt definite mai jos) care fac obiectul prezentei licențe. Orice utilizare a produsului, alta decât cea autorizată în temeiul prezentei licențe, este interzisă (în măsura în care o astfel de utilizare intră sub incidența unui drept al deținătorului drepturilor de autor asupra produsului). Produsul este furnizat în conformitate cu prevederile prezentei licențe în cazul în care licențiatorul (astfel cum este definit mai jos) a introdus următoarea mențiune imediat după mențiunea referitoare la dreptul de autor pentru produs: + Licențiat în baza EUPL +sau și-a exprimat, prin orice altă modalitate, dorința de a licenția produsul în baza EUPL. + +1.Definiții +În prezenta licență, următorii termeni au următoarele semnificații: +— Licență: prezenta licență. +— Produs original: produsul sau produsul informatic distribuit sau comunicat de către licențiator în baza prezentei licențe, disponibil sub formă de cod sursă, precum și sub formă de cod executabil, după caz. +— Produse derivate: produsele sau programele informatice create de către licențiat, pe baza produsului original sau a modificărilor aduse acestuia. Prezenta licență nu definește proporția modificării sau a dependenței de produsul original necesare pentru a putea cataloga produsul ca fiind produs derivat; această proporție este stabilită de legea dreptului de autor în vigoare în țara menționată la articolul 15. +— Produs: produsul original sau produsele derivate din acesta. +— Cod sursă: formă a produsului care poate fi citită de om și care este cea mai potrivită pentru a fi studiată și modificată de om. +— Cod executabil: orice cod care a fost în general compilat și care este destinat a fi interpretat ca program de către un computer. +— Licențiator: persoana fizică sau juridică care distribuie sau comunică produsul în baza unei licențe. +— Contribuitor(i): orice persoană fizică sau juridică care modifică produsul în baza licenței sau care contribuie în alt mod la crearea unui produs derivat. +— Licențiat sau dumneavoastră: orice persoană fizică sau juridică care folosește în orice mod produsul în conformitate cu prevederile licenței. +— Distribuire sau Comunicare: orice act de vânzare, oferire, împrumut, închiriere, distribuire, comunicare, transmitere sau punere în orice alt mod la dispoziție, online sau offline, a unor copii ale produsului sau furnizarea accesului la funcțiile principale ale acestuia oricărei alte persoane fizice sau juridice. + +2.Domeniul de aplicare al drepturilor conferite de licență +Licențiatorul vă oferă prin prezenta o licență internațională, scutită de redevențe, neexclusivă, care poate fi sublicențiată în următoarele scopuri, pe durata valabilității dreptului de autor dobândit pentru produsul original: +— folosirea produsului în orice circumstanțe și pentru orice tip de utilizare, +— reproducerea produsului, +— modificarea produsului și crearea de produse derivate bazate pe produsul original, +— comunicarea către public, inclusiv dreptul de a prezenta sau a pune la dispoziția publicului produsul sau copii ale acestuia și de a reda produsul în mod public, după caz, +— distribuirea produsului sau a copiilor acestuia, +— împrumutul sau închirierea produsului sau a copiilor acestuia, +— sublicențierea drepturilor asupra produsului sau a copiilor acestuia. +Aceste drepturi pot fi exercitate prin intermediul oricărui mijloc de comunicare, pe orice suport și în orice format, fie disponibil deja, fie care va fi inventat ulterior, în măsura în care acest lucru nu contravine legislației în vigoare. În țările în care se aplică drepturi morale, licențiatorul renunță la exercitarea dreptului său moral în măsura admisă de lege pentru ca licențierea drepturilor patrimoniale menționate mai sus să producă toate efectele. Licențiatorul nu solicită redevențe licențiatului și îi acordă drepturi de utilizare neexclusive pentru orice brevet de invenție deținut de licențiator, în măsura necesară pentru a se folosi de drepturile acordate asupra produsului în baza prezentei licențe. + +3.Comunicarea codului sursă +Licențiatorul poate furniza produsul fie sub formă de cod sursă, fie sub formă de cod executabil. În cazul în care produsul este furnizat sub formă de cod executabil, licențiatorul va furniza, de asemenea, o copie care poate fi citită de computer a codului sursă al produsului pentru fiecare copie a produsului pe care licențiatorul o distribuie, sau indică, într-o mențiune care urmează mențiunii privind dreptul de autor anexată produsului, o arhivă unde codul sursă este accesibil ușor și în mod gratuit pe toată durata perioadei în care licențiatorul continuă să distribuie sau să comunice produsul. + +4.Limitări ale dreptului de autor +Nicio prevedere a prezentei licențe nu are ca scop să priveze licențiatul de beneficiile rezultate din orice excepție sau limitare a drepturilor exclusive ale titularilor drepturilor asupra produsului, de încetarea acestor drepturi sau de alte limitări aplicabile acestora. + +5.Obligațiile licențiatului +Conferirea drepturilor menționate mai sus face obiectul unor restricții și obligații impuse licențiatului. Aceste obligații sunt următoarele: + +Dreptul de atribuire: licențiatul nu va aduce modificări niciunei mențiuni referitoare la dreptul de autor, la brevetul de invenție sau la marca înregistrată și niciunei mențiuni care face trimitere la licență și la renunțarea la garanții. Licențiatul trebuie să includă o copie a acestor mențiuni și o copie a licenței pentru fiecare copie a produsului pe care o distribuie sau o comunică. Licențiatul trebuie să se asigure de faptul că fiecare produs derivat poartă o mențiune vizibilă a faptului că produsul a fost modificat și data modificării. + +Clauza „copyleft”: în cazul în care licențiatul distribuie sau comunică copii ale produselor originale sau ale produselor derivate, această distribuire sau comunicare se va face în condițiile prevăzute de prezenta licență sau de o versiune ulterioară a prezentei licențe, sub rezerva distribuirii exprese a produsului original exclusiv în baza prezentei versiuni a licenței – de exemplu, prin comunicarea „Exclusiv EUPL v. 1.2”. Licențiatul (care devine licențiator) nu poate oferi sau impune alți termeni sau condiții suplimentare în ceea ce privește produsul sau produsul derivat care modifică sau restricționează condițiile prevăzute de licență. + +Clauza de compatibilitate: în cazul în care licențiatul distribuie sau comunică produse derivate sau copii ale acestora bazate atât pe produs, cât și pe un alt produs licențiat în baza unei licențe compatibile, această distribuire sau comunicare poate fi făcută în condițiile prevăzute de respectiva licență compatibilă. În sensul acestei clauze, prin „licență compatibilă” se înțelege oricare dintre licențele enumerate în anexa la prezenta licență. În cazul în care obligațiile licențiatului care derivă din licența compatibilă sunt în contradicție cu obligațiile care derivă din prezenta licență, vor prevala obligațiile prevăzute în licența compatibilă. + +Furnizarea codului sursă: în momentul distribuirii sau comunicării de copii ale produsului, licențiatul va furniza o copie care poate fi citită de computer a codului sursă sau va indica o arhivă în care se va putea accesa ușor și gratuit acest cod sursă pe parcursul întregii perioade în care licențiatul continuă să distribuie sau să comunice produsul. + +Protecția juridică: prezenta licență nu acordă permisiunea de a folosi denumirile comerciale, mărcile comerciale, mărcile de servicii sau numele licențiatorului, cu excepția situației în care acestea sunt necesare în cadrul unei utilizări rezonabile și normale pentru descrierea originii produsului și pentru reproducerea conținutului mențiunii referitoare la dreptul de autor. + +6.Lanțul de autori +Licențiatorul original garantează faptul că dreptul de autor pentru produsul original acordat prin prezenta este deținut de către acesta sau este licențiat în favoarea sa și că are competența și autoritatea de a acorda licența. Fiecare contribuitor garantează faptul că dreptul de autor asupra modificărilor pe care le aduce produsului este deținut de acesta sau este licențiat în favoarea sa și că are competența și autoritatea de a acorda licența. De fiecare dată când dumneavoastră acceptați licența, licențiatorul original și contribuitorii ulteriori vă acordă o licență asupra contribuțiilor lor aduse produsului, în condițiile prevăzute de prezenta licență. + +7.Renunțarea la garanții +Produsul este un produs în curs de elaborare îmbunătățit în mod continuu de mai mulți contribuitori. Acesta nu este un produs finalizat și, prin urmare, poate conține deficiențe sau erori („bugs”) inerente acestui tip de dezvoltare. Având în vedere motivul de mai sus, produsul este furnizat în baza licenței „în stadiul în care se află” și fără alte garanții de nicio natură privind produsul, inclusiv, și fără a se limita la acestea, comercializarea, compatibilitatea în anumite scopuri, absența defectelor sau a erorilor, acuratețea, respectarea drepturilor de proprietate intelectuală, altele decât dreptul de autor, astfel cum este menționat la articolul 6 din prezenta licență. Această renunțare la garanții reprezintă o parte esențială a licenței și o condiție pentru acordarea oricăror drepturi asupra produsului. + +8.Limitarea responsabilității +Cu excepția erorilor intenționate sau a daunelor cauzate în mod direct persoanelor fizice, licențiatorul nu va fi ținut răspunzător în nicio situație, pentru niciun fel de daune directe sau indirecte, materiale sau morale care derivă din licență sau din utilizarea produsului, inclusiv, și fără a se limita la acestea, daunele pentru pierderea fondului comercial, sau cele rezultate din întreruperea activității, nefuncționarea sau funcționarea necorespunzătoare a computerului, pierderea de date sau orice prejudicii comerciale, chiar dacă licențiatorul a fost informat asupra eventualității producerii unor astfel de daune. Cu toate acestea, licențiatorul va fi ținut răspunzător în baza legilor referitoare la răspunderea privind produsul în măsura în care astfel de legi se aplică în cazul produsului. + +9.Convenții suplimentare +Cu ocazia distribuirii produsului, puteți opta să încheiați o convenție suplimentară, cu definirea unor obligații sau servicii conforme cu prezenta licență. Cu toate acestea, acceptând astfel de obligații, licențiatul poate acționa doar în nume personal și pe răspunderea proprie, și nu în numele licențiatorului original sau al oricărui alt contribuitor, și doar dacă acceptă să despăgubească, să apere și să protejeze contribuitorul de orice răspundere angajată sau de orice plângeri formulate împotriva acestuia, din cauza faptului că licențiatul a acceptat să ofere o garanție sau o răspundere suplimentară. + +10.Acceptarea licenței +Prevederile prezentei licențe pot fi acceptate prin apăsarea butonului „Sunt de acord” din partea de jos a ferestrei care afișează textul prezentei licențe sau prin declararea consimțământului în orice alt mod similar, în conformitate cu normele aplicabile. Prin apăsarea acestui buton, licențiatul indică în mod clar și irevocabil faptul că acceptă prezenta licență, precum și toate clauzele și condițiile prevăzute de aceasta. De asemenea, licențiatul acceptă în mod irevocabil prezenta licență, împreună cu toate clauzele și condițiile prevăzute de aceasta, în momentul în care exercită orice drepturi conferite de articolul 2 al prezentei licențe, precum utilizarea produsului, crearea de către licențiat a unui produs derivat sau distribuirea sau comunicarea de către licențiat a produsului sau a unor copii ale acestuia. + +11.Informarea publicului +În cazul oricărei distribuiri sau comunicări a produsului de către licențiat prin mijloace de comunicare electronică (de exemplu, prin oferirea posibilității de a descărca produsul de la distanță), canalul sau mijlocul de distribuire (de exemplu, un site web) trebuie să furnizeze publicului cel puțin informațiile necesare în temeiul legii aplicabile privind licențiatorul, licența și modul în care aceasta poate fi accesată, acceptată, stocată și reprodusă de către licențiat. + +12.Încetarea licenței +Licența și drepturile conferite de aceasta încetează automat în cazul oricărei încălcări de către licențiat a prevederilor licenței. O astfel de încetare nu va duce la încetarea licențelor oricărei persoane care a intrat în posesia produsului de la licențiat în baza licenței, cu condiția ca aceste persoane să respecte în totalitate prevederile licenței. + +13.Diverse +Fără a aduce atingere articolului 9 de mai sus, licența reprezintă acordul integral dintre părți referitor la produs. În cazul în care orice prevedere a licenței este nulă sau nu poate fi aplicată în conformitate cu legislația aplicabilă, aceasta nu va afecta validitatea sau aplicabilitatea licenței în ansamblu. Aceste prevederi vor fi interpretate sau adaptate după cum se consideră necesar pentru a deveni valabile și aplicabile. Comisia Europeană poate publica alte versiuni lingvistice sau noi versiuni ale prezentei licenței sau versiuni actualizate ale apendicelui, în măsura în care acest lucru este necesar și rezonabil, fără a restrânge domeniul de aplicare al drepturilor conferite de licență. Noile versiuni ale licenței vor fi publicate cu un număr unic corespunzător versiunii. Toate versiunile lingvistice ale prezentei licențe, aprobată de Comisia Europeană, au valoare identică. Părțile pot alege să utilizeze oricare dintre versiunile lingvistice. + +14.Competență +Fără a aduce atingere acordului între părți, +— orice litigiu care decurge din interpretarea prezentei licențe, apărut între instituțiile, organismele sau agențiile Uniunii Europene, în calitate de licențiator, și un licențiat, va intra sub jurisdicția Curții de Justiție a Uniunii Europene, așa cum se prevede la articolul 272 din Tratatul privind funcționarea Uniunii Europene; +— orice litigiu între alte părți, care rezultă din interpretarea prezentei licențe, va intra sub jurisdicția exclusivă a instanței competente din locul în care licențiatorul își are reședința sau își derulează activitatea comercială principală. + +15.Dreptul aplicabil +Fără a aduce atingere acordului între părți, +— prezenta licență intră sub incidența legislației statului din Uniunea Europeană în care licențiatorul își are reședința sau sediul social; +— prezenta licență intră sub incidența legislației belgiene, în cazul în care licențiatorul nu își are reședința sau sediul social într-un stat membru al Uniunii Europene. + + +Apendice +„Licențele compatibile” în temeiul articolului 5 EUPL sunt: +— Licența publică generală GNU (GPL) v. 2, v. 3 +— Licența publică generală Affero GNU (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Licența publică Eclipse (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Licența publică Mozilla (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) pentru alte produse decât programe informatice +— Licența publică a Uniunii Europene (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence – Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+). +Comisia Europeană poate actualiza prezentul apendice, pentru a include versiunile ulterioare ale licențelor menționate mai sus, fără a da naștere unei noi versiuni ale EUPL, atât timp cât statele membre asigură drepturile acordate în temeiul articolului 2 din prezenta licență, precum și protejarea de însușirea exclusivă a codului sursă acoperit. +Toate celelalte modificări sau completări la prezentul apendice necesită producerea unei noi versiuni a EUPL. \ No newline at end of file diff --git a/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 SK.txt b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 SK.txt new file mode 100644 index 0000000..e3540ab --- /dev/null +++ b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 SK.txt @@ -0,0 +1,98 @@ +VEREJNÁ LICENCIA EURÓPSKEJ ÚNIE v. 1.2 +EUPL © Európska únia, 2007, 2016 +Táto verejná licencia Európskej únie („EUPL“) sa vzťahuje na diela (ako sú definované ďalej), ktoré sú poskytnuté podľa podmienok tejto licencie. Akékoľvek použitie diela v rozpore s podmienkami tejto licencie sa zakazuje (v rozsahu, v akom sa na takéto použitie vzťahuje ochrana právami nositeľa autorských práv k dielu). Dielo sa poskytuje podľa podmienok tejto licencie vtedy, ak poskytovateľ licencie (ako je definovaný ďalej) umiestnil nasledujúcu doložku hneď za upozornením o autorskoprávnej ochrane diela (tzv. doložkou o autorských právach): + Licencia poskytnutá podľa EUPL +alebo akýmkoľvek iným spôsobom prejavil svoju vôľu poskytnúť licenciu podľa EUPL. + +1.Vymedzenie pojmov +V tejto licencii majú tieto pojmy nasledujúci význam: +— „licencia“:táto licencia, +— „pôvodné dielo“:dielo alebo počítačový program rozširovaný alebo poskytovaný poskytovateľom licencie na základe tejto licencie, dostupný v zdrojovom kóde a prípadne aj v strojovom kóde, +— „odvodené diela“:diela alebo počítačové programy založené na pôvodnom diele alebo jeho úpravách, ktoré môže vytvoriť nadobúdateľ licencie. Táto licencia neurčuje rozsah úprav pôvodného diela alebo závislosti od pôvodného diela, ktoré sa vyžadujú na účely zatriedenia diela ako odvodeného diela; tento rozsah sa stanovuje autorským právom platným v krajine uvedenej v článku 15, +— „dielo“:pôvodné dielo alebo diela od neho odvodené, +— „zdrojový kód“:pre človeka čitateľná forma diela najvhodnejšia pre štúdium a úpravy, +— „strojový kód“:akýkoľvek kód, ktorý bol vo všeobecnosti zostavený, a to s cieľom, aby ho počítač spracoval ako program, +— „poskytovateľ licencie“:je fyzická osoba alebo právnická osoba, ktorá rozširuje alebo poskytuje dielo na základe tejto licencie, +— „spracovateľ(-lia)“:fyzická osoba alebo právnická osoba, ktorá upraví dielo podľa tejto licencie, alebo ktorá sa iným spôsobom podieľa na vytvorení odvodeného diela, +— „nadobúdateľ licencie“ alebo „Vy“:fyzická osoba alebo právnická osoba, ktorá akýmkoľvek spôsobom využíva dielo podľa podmienok tejto licencie, +— „rozširovanie“ alebo „poskytovanie“:akýkoľvek úkon predaja, odovzdania, požičania, nájmu, rozširovania, poskytnutia, prenášania alebo sprístupnenia rozmnoženín diela iným spôsobom, v režime online alebo offline, alebo poskytnutia prístupu k jeho základným funkciám v prospech ktorýchkoľvek tretích fyzických alebo právnických osôb. + +2.Rozsah práv udelených touto licenciou +Poskytovateľ licencie Vám týmto na obdobie platnosti ochrany autorských práv k pôvodnému dielu udeľuje celosvetovú, bezodplatnú, nevýhradnú licenciu, s možnosťou ďalšieho sublicencovania, na nasledovné použitie: +— používať dielo za akýchkoľvek okolností a akýmkoľvek spôsobom, +— zhotoviť rozmnoženinu diela, +— upraviť pôvodné dielo a vytvoriť odvodené dielo založené na pôvodnom diele, +— uskutočniť verejný prenos vrátane práva sprístupniť alebo vystaviť dielo alebo jeho rozmnoženiny na verejnosti a prípadne verejné vykonanie diela, +— rozširovať dielo alebo jeho rozmnoženiny, +— požičať alebo prenajať dielo alebo jeho rozmnoženiny, +— sublicenciou poskytnúť práva k dielu alebo jeho rozmnoženinám. +Tieto práva sa môžu uplatniť na akýchkoľvek v súčasnosti známych alebo v budúcnosti objavených médiách, nosičoch a formátoch, pokiaľ to umožňuje platné právo. V krajinách, v ktorých sa uplatňujú osobnostné práva, sa poskytovateľ licencie vzdáva výkonu svojich osobnostných práv, v zákonom povolenom rozsahu, s cieľom umožniť výkon majetkových práv uvedených vyššie. Poskytovateľ licencie udeľuje nadobúdateľovi licencie súhlas na bezodplatné, nevýhradné využitie patentov, ktorých majiteľom je poskytovateľ licencie, v rozsahu potrebnom na využitie práv k dielu udelených touto licenciou. + +3.Poskytnutie zdrojového kódu +Poskytovateľ licencie môže poskytnúť dielo buď vo forme zdrojového kódu, alebo v strojovom kóde. Ak sa dielo poskytuje v strojovom kóde, poskytovateľ licencie poskytne navyše ku každej ním rozširovanej rozmnoženine diela strojovo čitateľnú rozmnoženinu zdrojového kódu diela, alebo v oznámení za doložkou o autorských právach pripojenou k dielu uvedie zdroj, kde je tento zdrojový kód ľahko a voľne dostupný počas celého obdobia, keď poskytovateľ licencie rozširuje alebo poskytuje dielo. + +4.Obmedzenia autorských práv +Žiadne ustanovenie tejto licencie nemá za cieľ zbaviť nadobúdateľa licencie výhod vyplývajúcich z akýchkoľvek výnimiek alebo obmedzení výhradných práv nositeľov práv k dielu, zo zániku týchto práv alebo z iných uplatniteľných obmedzení týchto práv. + +5.Povinnosti nadobúdateľa licencie +Udelenie uvedených práv podlieha určitým obmedzeniam a povinnostiam, ktoré sa ukladajú nadobúdateľovi licencie. Ide o tieto povinnosti: + +Právo na zachovanie označení: Nadobúdateľ licencie zachová nedotknuté všetky doložky o autorských právach, patentoch alebo ochranných známkach a všetky doložky, ktoré sa vzťahujú na licenciu a vylúčenie záruky. Nadobúdateľ licencie musí do každej ním rozširovanej alebo poskytovanej rozmnoženiny diela zahrnúť kópiu takýchto doložiek, ako aj kópiu tejto licencie. Nadobúdateľ licencie musí akékoľvek odvodené dielo doplniť zreteľnou doložkou uvádzajúcou, že dielo bolo upravené, a dátum úpravy. + +Doložka nezmeniteľnosti podmienok (Copyleft clause): Ak nadobúdateľ licencie rozširuje alebo poskytuje rozmnoženiny pôvodného diela alebo odvodených diel, takéto rozširovanie alebo poskytovanie sa uskutoční podľa podmienok tejto licencie alebo podľa podmienok neskoršej verzie tejto licencie s výnimkou prípadov, keď sa pôvodné dielo výslovne rozširuje iba podľa tejto verzie licencie – napríklad označením „výlučne EUPL v. 1.2“. Nadobúdateľ licencie (ktorý sa stáva poskytovateľom licencie) nemôže k dielu alebo odvodenému dielu ponúkať alebo ukladať doplňujúce podmienky, ktoré menia alebo obmedzujú podmienky tejto licencie. + +Doložka zlučiteľnosti: Ak nadobúdateľ licencie rozširuje alebo poskytuje odvodené diela alebo ich rozmnoženiny založené tak na diele, ako aj na inom diele licencovanom na základe zlučiteľnej licencie, takéto rozširovanie alebo poskytovanie sa môže uskutočniť podľa podmienok takejto zlučiteľnej licencie. Na účely tejto doložky sa za „zlučiteľnú licenciu“ považujú licencie vymenované v dodatku k tejto licencii. Ak sú povinnosti nadobúdateľa licencie podľa zlučiteľnej licencie v rozpore s jeho povinnosťami podľa tejto licencie, sú rozhodujúce povinnosti vyplývajúce zo zlučiteľnej licencie. + +Poskytovanie zdrojového kódu: Pri rozširovaní alebo poskytovaní rozmnoženín diela poskytne nadobúdateľ licencie strojovo čitateľnú rozmnoženinu zdrojového kódu diela alebo uvedie zdroj, kde je tento zdrojový kód ľahko a voľne dostupný počas celého obdobia, keď nadobúdateľ licencie rozširuje alebo poskytuje dielo. + +Právna ochrana: Touto licenciou sa neudeľuje povolenie na použitie obchodných mien, ochranných známok, ochranných známok pre služby alebo označení poskytovateľa licencie, iba ak si to vyžaduje ich primerané a obvyklé použitie pri opise pôvodu diela a reprodukovaní obsahu doložky o autorských právach. + +6.Reťazec autorstva +Pôvodný poskytovateľ licencie zaručuje, že je oprávneným nositeľom autorského práva alebo nadobúdateľom licencie k pôvodnému dielu, ktoré je predmetom tejto licencie, a že má právo udeliť túto licenciu. Každý spracovateľ zaručuje, že je oprávneným nositeľom autorského práva k úpravám, ktoré pridal k dielu alebo nadobúdateľom licencie k týmto úpravám, a že má právo udeliť túto licenciu. Vždy, keď Vy ako nadobúdateľ licencie prijmete podmienky tejto licencie, udeľujú Vám podľa podmienok tejto licencie pôvodný poskytovateľ licencie a každý nasledujúci spracovateľ licenciu k tomu, čím na dielo prispeli. + +7.Vylúčenie záruky +Toto dielo je dielom vo vývoji, ktoré je neustále vylepšované množstvom spracovateľov. Nie je ukončeným dielom, a preto môže obsahovať nedostatky alebo logické chyby v programe príznačné pre tento druh vývoja. Z týchto dôvodov sa dielo podľa tejto licencie poskytuje „ako stojí a leží“ a bez akýchkoľvek záruk týkajúcich sa diela, okrem iného bez záruk za obchodovateľnosť, vhodnosť na konkrétny účel, neexistenciu nedostatkov a chýb, presnosť, neexistenciu porušenia práv duševného vlastníctva iných ako autorských práv uvedených v článku 6 tejto licencie. Toto vylúčenie záruky je podstatnou súčasťou tejto licencie a podmienkou pre udelenie akýchkoľvek práv k dielu. + +8.Vylúčenie zodpovednosti +S výnimkou prípadov úmyselného protiprávneho konania alebo škôd priamo spôsobených fyzickým osobám poskytovateľ licencie v žiadnom prípade nezodpovedá za žiadne priame alebo nepriame, materiálne alebo morálne škody akéhokoľvek druhu, ktoré vyplývajú z licencie alebo použitia diela, okrem iného vrátane poškodenia dobrého mena (goodwill), zastavenia prác, zlyhania alebo nesprávneho fungovania počítača, straty údajov alebo akejkoľvek škody obchodnej povahy, a to aj v prípade, ak poskytovateľ licencie bol na možnosť takejto škody upozornený. Poskytovateľ licencie však zodpovedá podľa právnych predpisov o zodpovednosti za chybné výrobky v rozsahu, v akom sa takéto predpisy vzťahujú na dielo. + +9.Dodatočné dohody +Pri rozširovaní diela sa môžete (Vy) rozhodnúť uzavrieť dodatočné dohody, v ktorých sa vymedzia povinnosti alebo služby v súlade s touto licenciou. Pri preberaní takýchto povinností však môžete (Vy) konať len vo vlastnom mene a na vlastnú zodpovednosť, a nie v mene pôvodného poskytovateľa licencie alebo akéhokoľvek ďalšieho spracovateľa, a len ak sa (Vy) zaviažete každého spracovateľa odškodniť, brániť a zbaviť zodpovednosti alebo nárokov uplatnených voči takémuto spracovateľovi v dôsledku toho, že ste prijali akúkoľvek záruku alebo dodatočnú zodpovednosť. + +10.Prijatie podmienok licencie +Podmienky tejto licencie možno prijať kliknutím na ikonku „Súhlasím“ umiestnenú pod spodnou časťou okna, ktoré zobrazuje text tejto licencie, alebo vyjadrením súhlasu akýmkoľvek iným podobným spôsobom v súlade s pravidlami platného práva. Kliknutím na túto ikonku vyjadrujete jednoznačné a neodvolateľné prijatie tejto licencie a všetkých jej podmienok. Podobne túto licenciu a všetky jej podmienky neodvolateľne prijímate aj využitím akéhokoľvek práva, ktoré sa Vám udeľuje na základe článku 2 tejto licencie, ako napríklad použitím diela, vytvorením odvodeného diela alebo rozširovaním alebo poskytovaním diela alebo jeho rozmnoženín. + +11.Informácie pre verejnosť +V prípadoch akéhokoľvek rozširovania alebo poskytovania diela využitím prostriedkov elektronickej komunikácie (napríklad ponukou na stiahnutie diela zo vzdialeného miesta) musí distribučný kanál alebo médium (napríklad webová stránka) poskytnúť verejnosti aspoň informácie požadované platným právom týkajúce sa poskytovateľa licencie, licencie a toho, ako k nej nadobúdateľ licencie získa prístup, ako ju môže uzatvoriť, uložiť a reprodukovať. + +12.Ukončenie licencie +Licencia a práva udelené na jej základe bez ďalšieho zaniknú v prípade akéhokoľvek porušenia podmienok tejto licencie nadobúdateľom licencie. Týmto zánikom nezaniknú licencie žiadnych osôb, ktoré získali dielo od nadobúdateľa licencie podľa tejto licencie za podmienky, že takéto osoby budú v plnom rozsahu dodržiavať podmienky tejto licencie. + +13.Rôzne +Bez toho, aby boli dotknuté ustanovenia článku 9 vyššie, licencia predstavuje úplnú dohodu medzi stranami vo vzťahu k dielu. Ak je podľa platného práva akékoľvek ustanovenie tejto licencie neplatné alebo nevykonateľné, nemá to vplyv na platnosť a vykonateľnosť licencie ako celku. Takéto ustanovenie sa bude vykladať alebo sa prepracuje tak, aby sa stalo platné a vykonateľné. Európska komisia môže, ak je to žiaduce a primerané, uverejniť ostatné jazykové verzie alebo nové verzie tejto licencie alebo aktualizované verzie dodatku, pričom sa neobmedzí rozsah práv udelených licenciou. Nové verzie tejto licencie sa uverejnia s nezameniteľným poradovým číslom verzie. Všetky jazykové verzie tejto licencie, ktoré schválila Európska komisia, sú rovnocenné. Zmluvné strany môžu využívať tú jazykovú verziu, ktorú si vyberú. + +14.Súdna príslušnosť +Bez toho, aby boli dotknuté osobitné dohody medzi zmluvnými stranami: +— pre akékoľvek spory medzi inštitúciami, orgánmi, úradmi alebo agentúrami Európskej únie ako poskytovateľom licencie a ktorýmkoľvek nadobúdateľom licencie vyplývajúce z výkladu tejto licencie je príslušný Súdny dvor Európskej únie, v zmysle článku 272 Zmluvy o fungovaní Európskej únie, +— akékoľvek spory medzi inými stranami, ktoré vyplývajú z výkladu tejto licencie, sú vo výhradnej právomoci súdu príslušného podľa miesta pobytu poskytovateľa licencie alebo miesta, kde tento vykonáva svoju hlavnú podnikateľskú činnosť. + +15.Rozhodné právo +Bez toho, aby boli dotknuté osobitné dohody medzi zmluvnými stranami: +— táto licencia sa spravuje právom členského štátu Európskej únie, v ktorom má poskytovateľ licencie pobyt alebo sídlo, +— ak poskytovateľ licencie nemá pobyt alebo sídlo v členskom štáte Európskej únie, táto licencia sa spravuje belgickým právom. + + +Dodatok +„Zlučiteľné licencie“ podľa článku 5 EUPL sú: +— GNU General Public License (GPL) v. 2, v. 3, +— GNU Affero General Public License (AGPL) v. 3, +— Open Software License (OSL) v. 2.1, v. 3.0, +— Eclipse Public License (EPL) v. 1.0, +— CeCILL v. 2.0, v. 2.1, +— Mozilla Public Licence (MPL) v. 2, +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3, +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for works other than software, +— European Union Public Licence (EUPL) v. 1.1, v. 1.2, +— Québec Free and Open-Source Licence – Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+). +Európska komisia môže tento dodatok aktualizovať, aby zahŕňal neskoršie verzie uvedených licencií, bez zavedenia novej verzie EUPL, pokiaľ uvedené licencie zabezpečujú práva udelené článkom 2 tejto licencie a chránia zdrojový kód, ktorý je jej predmetom, pred výhradným privlastnením. +Všetky ostatné zmeny alebo doplnenia tohto dodatku si vyžadujú novú verziu EUPL. \ No newline at end of file diff --git a/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 SL.txt b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 SL.txt new file mode 100644 index 0000000..8046186 --- /dev/null +++ b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 SL.txt @@ -0,0 +1,97 @@ +JAVNA LICENCA EVROPSKE UNIJE v. 1.2 +EUPL © Evropska unija 2007, 2016 +Ta javna licenca Evropske unije (v nadaljnjem besedilu: EUPL) se uporablja za delo (kakor je opredeljeno spodaj), zagotovljeno pod pogoji iz te licence. Vsaka uporaba dela, ki ni dovoljena s to licenco, je prepovedana (kolikor je ta uporaba zajeta v pravici imetnika avtorske pravice tega dela). Delo je zagotovljeno pod pogoji iz te licence, če je dajalec licence (kakor je opredeljeno spodaj) dodal naslednje obvestilo takoj za obvestilom o avtorski pravici za delo: Licencirano po EUPL +ali je na kateri koli drugi način izrazil svojo pripravljenost, da delo licencira na podlagi EUPL. + +1.Opredelitve pojmov +V tej licenci imajo naslednji izrazi naslednji pomen: +— „licenca“:ta licenca; +— „izvirnik dela“:delo ali programska oprema, ki jo distribuira ali posreduje dajalec licence na podlagi te licence ter je na voljo kot „izvirna koda“ in po potrebi tudi kot „izvršljiva koda“; +— „izvedena dela“:dela ali programska oprema, ki jih lahko ustvari pridobitelj licence na podlagi izvirnika dela ali njegovih sprememb. Ta licenca ne opredeljuje obsega sprememb ali odvisnosti od izvirnika dela, ki se zahteva za opredelitev dela kot izvedenega dela; ta obseg je določen v avtorskem pravu, ki se uporablja v državi v skladu s členom 15; +— „delo“:izvirnik dela ali njegova izvedena dela; +— „izvirna koda“:oblika dela, ki je najbolj primerna, da jo lahko ljudje proučijo in spreminjajo; +— „izvršljiva koda“:vsaka koda, ki je bila splošno sestavljena in naj bi jo računalnik prepoznal kot program; +— „dajalec licence“:fizična ali pravna oseba, ki distribuira ali posreduje delo na podlagi licence; +— „sodelavec“ oz. „sodelavci“:vsaka fizična ali pravna oseba, ki spremeni delo iz licence ali drugače prispeva k nastanku izvedenega dela; +— „pridobitelj licence“ ali „Vi“:vsaka fizična ali pravna oseba, ki kakor koli uporablja delo pod pogoji iz licence; +— „distribucija“ ali „posredovanje“:vsako dejanje prodaje, dajanja, posojanja, dajanja v najem, distribuiranja, posredovanja, prenašanja ali omogočanja razpolaganja po spletu ali zunaj njega s kopijami dela ali zagotavljanje dostopa do ključnih funkcij drugim fizičnim ali pravnim osebam. + +2.Obseg pravic, podeljenih z licenco +Dajalec licence Vam s tem podeli svetovno, brezplačno, neizključno licenco, ki jo je mogoče podlicencirati, za čas trajanja avtorske pravice, podeljene izvirniku dela, za: +— uporabo dela v vseh okoliščinah in za vso rabo, +— reprodukcijo dela, +— spremembo dela in izdelavo izvedenih del na podlagi dela, +— posredovanje dela javnosti, vključno s pravico do dajanja na razpolago ali prikazovanja dela ali njegovih kopij v javnosti in po potrebi njegovega javnega izvajanja, +— distribucijo dela ali njegovih kopij, +— izposojo in dajanje v najem dela ali njegovih kopij, +— pravico podlicenciranja dela ali njegovih kopij. +Te pravice se lahko izvršujejo na katerem koli mediju, na katerem koli nosilcu in v kakršnih koli formatih, bodisi že znanih bodisi pozneje izumljenih, če to dovoljuje pravo, ki se uporablja. V državah, kjer veljajo moralne pravice, se dajalec licence odpove svoji pravici do izvrševanja svoje moralne pravice v obsegu, ki ga dovoljuje pravo, da se zagotovi večja učinkovitost licence za zgoraj navedene ekonomske pravice. Dajalec licence pridobitelju licence podeli brezplačno, neizključno pravico do uporabe za vse patente, ki jih ima dajalec licence, v obsegu, ki je potreben za uporabo pravic, podeljenih v zvezi z delom na podlagi te licence. + +3.Posredovanje izvirne kode +Dajalec licence lahko zagotovi delo v obliki izvirne kode ali kot izvršljivo kodo. Če je delo zagotovljeno kot izvršljiva koda, zagotovi dajalec licence strojno berljivo kopijo izvirne kode dela vsaki kopiji dela, ki jo distribuira, ali v obvestilu, ki sledi obvestilu o avtorski pravici in je priloženo k delu, shranjevalnik, na katerem je izvirna koda enostavno in prosto dostopna, dokler še distribuira ali posreduje delo. + +4.Omejitve avtorske pravice +S to licenco ne sme biti pridobitelj licence na noben način prikrajšan glede svojih koristi na podlagi kakršne koli izjeme ali omejitve izključnih pravic lastnikov pravic v zvezi z delom, prenehanjem teh pravic ali drugimi omejitvami, ki se glede tega uporabljajo. + +5.Obveznosti pridobitelja licence +Za podelitev zgoraj navedenih pravic veljajo nekatere omejitve in obveznosti za pridobitelja licence. Te obveznosti so: + +Pravica do označevanja: pridobitelj licence ne bo posegal v obvestila o avtorski pravici, patentu ali blagovnih znamkah in obvestila, ki se nanašajo na licenco in izjavo o jamstvih. Pridobitelj licence mora vključiti kopijo takšnih obvestil in kopijo licence v vsako kopijo dela, ki ga distribuira ali posreduje. Pridobitelj licence mora vsako izvedeno delo opremiti z jasnimi obvestili, da je bilo delo spremenjeno, in navesti datum spremembe. + +Klavzula o svobodni avtorski pravici (Copyleft): če pridobitelj licence distribuira ali posreduje kopije izvirnikov del ali izvedenih del, bo ta distribucija ali posredovanje opravljeno pod pogoji iz te licence ali poznejše različice te licence, razen če je izvirnik dela izrecno distribuiran samo po tej različici licence – na primer z navedbo „izključno po EUPL v.1.2“. Pridobitelj licence (ki postane dajalec licence) ne sme ponuditi ali določiti nobenih dodatnih pogojev za delo ali izvedeno delo, ki spreminjajo ali omejujejo pogoje iz licence. + +Klavzula o združljivosti: če pridobitelj licence distribuira ali posreduje izvedena dela ali njihove kopije na podlagi dela in drugega dela, ki je licencirano po združljivi licenci, se ta distribucija ali posredovanje lahko opravi pod pogoji iz združljive licence. Za namene te klavzule se „združljiva licenca“ nanaša na licence, navedene v Dodatku k tej licenci. Če so obveznosti pridobitelja licence v združljivi licenci v nasprotju z njegovimi obveznostmi v tej licenci, obveznosti v združljivi licenci prevladajo. + +Zagotavljanje izvirne kode: pri distribuiranju ali posredovanju kopij dela, bo dajalec licence zagotovil strojno berljivo kopijo izvirne kode ali navedel shranjevalnik, kjer bo ta koda enostavno in prosto dostopna, dokler dajalec licence še distribuira ali posreduje delo. + +Pravno varstvo: ta licenca ne dovoljuje uporabe trgovskih imen, blagovnih znamk, storitvenih znamk ali imen dajalca licence, razen kot se to zahteva za primerno in običajno uporabo pri opisovanju izvora dela ter reprodukciji vsebine obvestila o avtorski pravici. + +6.Avtorska veriga +Prvotni dajalec licence jamči, da je v skladu s to licenco lastnik avtorske pravice izvirnika dela ali da mu je bila dodeljena licenca in da je pristojen in upravičen za dajanje licence. Vsak sodelavec jamči, da je lastnik avtorske pravice za spremembe, ki jih je vnesel v delo, ali da mu je bila dodeljena licenca in je pristojen in upravičen za dajanje licence. Vsakič, ko prejmete licenco, Vam prvotni dajalec licence in vsi nadaljnji sodelavci podelijo licenco za svoje prispevke k delu pod pogoji iz te licence. + +7.Izjava o omejitvi jamstva +Delo se razume kot delo, ki se stalno razvija in ki ga nenehno izboljšujejo številni sodelavci. Ni dokončano delo in lahko zato vsebuje napake ali „hrošče“, ki so povezani s tovrstnim razvojem. Iz zgoraj navedenih razlogov se delo zagotavlja na podlagi licence po načelu „takšno kot je“ in brez kakršnih koli jamstev glede dela, kar vključuje najmanj tržljivost, ustreznost za določen namen, odsotnost okvar ali napak, natančnost, spoštovanje pravic intelektualne lastnine razen avtorske pravice, kot je navedeno v členu 6 te licence. Ta izjava o jamstvih je bistveni del te licence in pogoj za podelitev kakršnih koli pravic v zvezi z delom. + +8.Izjava o omejitvi odgovornosti +Razen v primerih namerne kršitve ali škode, neposredno povzročene fizičnim osebam, dajalec licence ne bo v nobenem primeru odgovoren za kakršno koli neposredno ali posredno materialno ali moralno škodo, nastalo na podlagi licence ali uporabe dela, med drugim vključno s škodo zaradi izgube dobrega imena, prekinitve dela, okvare ali motnje v delovanju računalnika, izgube podatkov ali kakršne koli poslovne škode, čeprav je bil dajalec licence opozorjen na možnost nastanka takšne škode. Vendar bo dajalec licence odgovoren po zakonskih predpisih o odgovornosti za proizvode, če takšni predpisi veljajo za delo. + +9.Dodatni dogovori +Pri distribuiranju dela se lahko odločite za sklenitev dodatnega sporazuma, v katerem so opredeljene obveznosti ali storitve, skladne s to licenco. Vendar če obveznosti prevzamete, lahko delujete samo v lastnem imenu in izključno na podlagi lastne odgovornosti, ne pa v imenu prvotnega dajalca licence ali katerega koli drugega sodelavca, in samo, če se strinjate, da boste vsakemu sodelavcu povrnili škodo, ga branili in izvzeli iz kakršnih koli nastalih odgovornosti ali zahtevkov na njegov račun, ki bi izhajali iz tega, da ste prevzeli jamstvo ali dodatno odgovornost. + +10.Sprejetje licence +Določbe v licenci je mogoče sprejeti s klikom na ikono „Strinjam se“ („I agree“), ki je pod spodnjim delom okna z besedilom te licence, ali s kakršno koli podobno potrditvijo v skladu s pravili prava, ki se uporablja. S klikom na to ikono boste izrazili nedvoumno in nepreklicno sprejetje te licence in vseh njenih pogojev. Podobno nepreklicno sprejemate to licenco in vse njene pogoje pri uveljavljanju pravic, ki so Vam bile podeljene s členom 2 te licence, kot je uporaba dela, izdelava izvedenih del ali distribucija oz. posredovanje dela ali njegovih kopij. + +11.Obveščanje javnosti +Če boste distribuirali ali posredovali delo s sredstvi elektronskega posredovanja (na primer s ponudbo za prenos dela z oddaljenega mesta), mora distribucijski kanal ali medij (na primer spletna stran) navajati vsaj informacije za javnost, ki se zahtevajo v skladu s pravom, ki se uporablja v zvezi z dajalcem licence, licenco in načinom, kako je licenca lahko dostopna, ter kako jo pridobitelj licence lahko sklene, shrani in reproducira. + +12.Prenehanje licence +Licenca in pravice, ki se podelijo na njeni podlagi, bodo avtomatsko prenehale z vsakršno kršitvijo pogojev iz licence s strani pridobitelja licence. Takšno prenehanje ne bo veljalo za licence oseb, ki so prejele delo od pridobitelja licence na podlagi te licence, če te osebe še naprej v celoti ravnajo v skladu s pogoji licence. + +13.Razno +Brez poseganja v člen 9 licenca pomeni popoln dogovor med strankami glede dela. Če je katera koli določba iz licence neveljavna ali neizvršljiva po pravu, ki se uporablja, to ne bo vplivalo na veljavnost in izvršljivost licence kot celote. Takšna določba se bo razlagala ali bo spremenjena tako, da bo veljavna in izvršljiva. Če je potrebno in primerno, lahko Evropska komisija objavi druge jezikovne različice ali nove različice te licence ali posodobljene različice Dodatka, ne da bi zmanjšala obseg pravic, ki so bile licencirane. Nove različice licence bodo objavljene s številko edinstvene različice. Vse jezikovne različice te licence, ki jih je odobrila Evropska komisija, so enakovredne. Stranke lahko uporabljajo jezikovne različice po svoji izbiri. + +14.Pristojnost +Brez poseganja v posebne sporazume med strankami: +— bo za vse pravne spore zaradi razlage te licence, ki nastanejo med institucijami, organi, uradi ali agencijami Evropske unije kot dajalcem licence in katerim koli prejemnikom licence, veljala sodna pristojnost Sodišča Evropske unije, kot je določeno v členu 272 Pogodbe o delovanju Evropske unije, +— za vse pravne spore med strankami, ki izhajajo iz razlage te licence, bo veljala izključna pristojnost zadevnega sodišča države, v kateri ima dajalec licence prebivališče ali kjer opravlja svojo osnovno dejavnost. + +15.Pravo, ki se uporablja +Brez poseganja v posebne sporazume med strankami: +— to licenco ureja pravo države Evropske unije, v kateri ima dajalec licence svoj sedež, prebivališče ali statutarni sedež, +— to licenco ureja belgijsko pravo, če dajalec licence nima sedeža, prebivališča ali statutarnega sedeža v državi članici Evropske unije. + + +Dodatek +„Združljive licence“ v skladu s členom 5 EUPL so: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution–ShareAlike v. 3.0 Unported (CC BY–SA 3.0) za dela razen programske opreme +— Javna licenca Evropske unije (EUPL) v. 1.1, v. 1.2 +— Javna licenca Québeca – vzajemnost (LiLiQ–R) ali močna vzajemnost (LiLiQ–R+). +Evropska komisija lahko ta dodatek dopolni s poznejšimi različicami zgoraj navedenih licenc, ne da bi pri tem ustvarila novo različico EUPL, če te različice zagotavljajo pravice iz člena 2 te licence in izvirno kodo, ki je njen predmet, varujejo pred izključno prisvojitvijo. +Vsakršna druga sprememba ali dopolnilo k temu dodatku zahteva novo različico EUPL. \ No newline at end of file diff --git a/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 SV.txt b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 SV.txt new file mode 100644 index 0000000..75959a0 --- /dev/null +++ b/vendor/FeldarianBaseLibrary/EUPL-1.2/EUPL v1_2 SV.txt @@ -0,0 +1,97 @@ +EUROPEAN UNION PUBLIC LICENCE (LICENS TILL ÖPPEN KÄLLKOD FRÅN EUROPEISKA UNIONEN) v. 1.2 +EUPL © the European Union 2007, 2016 +Denna licens till öppen källkod från Europeiska unionen (EUPL), avser det verk (enligt definitionen nedan) som tillhandahålls på de villkor som anges i licensen. All användning av verket, som inte är tillåten enligt denna licens, är förbjuden (i den mån användningen i fråga omfattas av en rättighet som tillkommer innehavaren av upphovsrätten till verket). Verket tillhandahålls enligt villkoren i denna licens när licensgivaren (enligt definitionen nedan) har placerat följande meddelande omedelbart efter upphovsrättsmeddelandet avseende originalverket: + Licensierat enligt EUPL +eller på annat sätt har givit uttryck för sin avsikt att licensiera enligt EUPL. + +1.Definitioner I förevarande licens har följande uttryck angiven innebörd: +— licensen: denna licens. +— originalverk: det verk eller den programvara som sprids eller kommuniceras av licensgivaren enligt denna licens och som, beroende på omständigheterna, är tillgänglig i form av källkod eller exekverbar kod. +— härledda verk: de verk eller den programvara som licenstagaren kan skapa på grundval av originalverket eller nya versioner av detta. I denna licens definieras inte den grad av ändring eller det beroende av det ursprungliga verket som krävs för en klassificering som härlett verk. Detta bestäms enligt den upphovsrättslagstiftning som är tillämplig i det land som anges i artikel 15. +— verket: originalverket eller verk som är härledda från detta. +— källkod: den för människan läsbara formen av verket, som lättast kan granskas och ändras av människor. +— den exekverbara koden: all kod som i allmänhet kompilerats och som är avsedd att läsas som ett program av en dator. +— licensgivaren: den fysiska eller juridiska person som sprider eller kommunicerar det verk som licensen gäller. +— bidragslämnare: en fysisk eller juridisk person som bearbetar det verk licensen gäller, eller på annat sätt bidrar till att skapa ett härlett verk. +— licenstagaren eller du: en fysisk eller juridisk person som använder verket enligt villkoren i licensen. +— spridning eller kommunikation: varje handling som syftar till att sälja, ge, låna ut, hyra ut, distribuera, kommunicera, sända eller på annat sätt, online eller offline, göra kopior av verket tillgängliga eller ge tillgång till dess väsentliga funktioner för en annan fysisk eller juridisk person. + +2.Räckvidden av de rättigheter som beviljas enligt licensen +Licensgivaren ger dig härmed en världsomfattande, royaltyfri, icke exklusiv licens, som kan licensieras vidare och som ger dig rätt att under giltighetstiden av den upphovsrätt som gäller för originalverket göra följande: +— Använda verket i alla sammanhang och för alla ändamål. +— Mångfaldiga verket. +— Ändra verket och framställa härledda verk på grundval av verket. +— Kommunicera verket till allmänheten, vilket, beroende på omständigheterna, inkluderar en rätt att göra det tillgängligt eller visa det, eller kopior av det, för allmänheten och att framföra verket offentligt. +— Sprida verket eller kopior av det. +— Låna eller hyra ut verket eller kopior av det. +— Underlicensiera rättigheter till verket eller kopior av detta. +Dessa rättigheter kan utövas på valfritt lagringsmedium, underlag och format, oberoende av om det är känt nu eller kommer att uppfinnas i framtiden, i den mån detta är tillåtet enligt gällande rätt. I de länder där ideella rättigheter är tillämpliga frånsäger sig licensgivaren sin rätt att utöva sina ideella rättigheter, i den mån detta är rättsligt tillåtet, för att göra licensen till de ovan angivna ekonomiska rättigheterna verkningsfull. Licensgivaren beviljar licenstagaren en royaltyfri, icke-exklusiv nyttjanderätt till eventuella patent som innehas av licensgivaren i den mån det är nödvändigt för att dra nytta av de rättigheter till verket som medges enligt denna licens. + +3.Tillhandahållande av källkod +Licensgivaren kan tillhandahålla verket i form av antingen källkod eller exekverbar kod. Om verket tillhandahålls i form av exekverbar kod, tillhandahåller licensgivaren dessutom en maskinläsbar kopia av källkoden till verket tillsammans med varje kopia av verket som licensgivaren sprider eller uppger, i ett meddelande som åtföljer upphovsrättsmeddelandet på verket, en lagringsplats där källkoden enkelt och gratis är tillgänglig så länge licensgivaren fortsätter att sprida eller kommunicera verket. + +4.Upphovsrättens inskränkningar +Ingenting i denna licens är avsett att frånta licenstagaren förmånen av något undantag från eller någon inskränkning av de exklusiva rättigheter som tillhör innehavarna av rättigheterna till verket, till följd av dessa rättigheters konsumtion eller av andra gällande inskränkningar av dessa. + +5.Licenstagarens skyldigheter +Beviljandet av ovan angivna rättigheter är föremål för vissa begränsningar och skyldigheter som åläggs licenstagaren. Dessa skyldigheter är följande: + +Rätt att bli angiven som upphovsman och respekträtt: Licenstagaren ska bevara alla meddelanden om upphovsrätt, patent eller varumärken intakta, liksom alla meddelanden som hänvisar till licensen och till friskrivning från garantier. Licenstagaren måste inkludera en kopia av dessa meddelanden och en kopia av licensen i varje kopia av verket som han/hon sprider eller kommunicerar. Licenstagaren måste ombesörja att eventuella härledda verk är försedda med tydlig uppgift om att verket har ändrats, samt om tidpunkten för ändringen. + +Copyleft-klausul: Om licenstagaren sprider eller kommunicerar kopior av originalverket eller härledda verk som grundas på originalverket, ska denna spridning eller kommunikation ske enligt villkoren i denna licens eller i en senare version av denna licens, om inte originalverket uttryckligen bara får spridas med stöd av denna version av licensen – t.ex. genom att kommunicera ”endast EUPL v. 1.2”. Licenstagaren (som blir licensgivare) kan inte erbjuda eller ålägga ytterligare villkor avseende verket eller härledda verk som ändrar eller begränsar villkoren i denna licens. + +Kompatibilitetsklausul: Om licenstagaren sprider och/eller kommunicerar härledda verk eller kopior av sådana, som grundas på originalverket och annat verk som licensieras enligt en kompatibel licens, kan denna spridning eller kommunikation ske enligt villkoren i den kompatibla licensen. Med ”kompatibel licens” avses beträffande denna klausul de licenser som anges i det tillägg som fogas till denna licens. För det fall att licenstagarens skyldigheter enligt den kompatibla licensen strider mot hans/hennes skyldigheter enligt denna licens, ska skyldigheterna enligt den kompatibla licensen äga företräde. + +Tillhandahållande av källkod: Vid spridningen eller kommunikationen av kopior av verket ska licenstagaren tillhandahålla en maskinläsbar kopia av källkoden eller ange en lagringsplats där denna källkod är lätt och gratis tillgänglig så länge licensgivaren fortsätter att sprida eller kommunicera verket. + +Rättsligt skydd: Denna licens medför inte rätt att använda licensgivarens varunamn, varumärken, servicemärken eller namn, med undantag för i den omfattning detta skäligen och enligt gängse bruk är nödvändigt för att beskriva verkets ursprung och återge innehållet i upphovsrättsmeddelandet. + +6.Upphovsmannakedja +Den ursprungliga licensgivaren garanterar att upphovsrätten till det originalverk som beviljas enligt licensen ägs av honom/henne eller licensierats till honom/henne och att han/hon har befogenhet och rätt att bevilja licensen. Varje bidragslämnare garanterar att upphovsrätten till de ändringar han/hon tillfört verket ägs av honom/henne eller licensierats till honom/henne och att han/hon har befogenhet och rätt att bevilja licensen. Varje gång du godkänner licensen beviljas du, enligt villkoren i licensen, av den ursprungliga licensgivaren och därefter följande bidragslämnare en licens till deras bidrag till verket. + +7.Friskrivning från garantier +Verket är ett ännu ej fullbordat verk, som kontinuerligt förbättras av en rad bidragslämnare. Det är inte ett färdigställt verk och kan därför innehålla felaktigheter och programfel, vilket är kännetecknande för denna typ av utveckling. Av ovanstående skäl tillhandahålls verket enligt licensen i ”befintligt skick” och utan någon typ av garanti med avseende på verket, vilket bland annat inbegriper godtagbar kvalitet, lämplighet för ett visst ändamål, frånvaro av defekter och felaktigheter, exakthet, garantier för att andra immaterialrättigheter än upphovsrätt enligt punkt 6 i licensen inte kränks. Denna friskrivning är en väsentlig del av licensen och ett villkor för beviljande av rättigheter till verket. + +8.Ansvarsfriskrivning +Med undantag för fall av avsiktliga fel eller skador som direkt drabbar fysiska personer, kommer licensgivaren inte i något fall att ansvara för direkt eller indirekt, materiell eller ideell skada av något slag som uppstår på grund av licensen eller användningen av verket, däribland, men inte endast, ersättning för förlorad goodwill, driftstopp, datafel eller störningar, förlust av data eller annan kommersiell skada, oberoende av om licensgivaren underrättats om att sådan skada kan inträffa. Licensgivaren är dock ansvarig enligt lagstiftning om produktansvar i den mån sådan lagstiftning är tillämplig på verket. + +9.Tilläggsavtal +Vid spridning av verket eller härledda verk kan du välja att ingå ett tilläggsavtal som definierar skyldigheter eller tjänster som är förenliga med licensen. Om du accepterar skyldigheter kan du dock endast agera för din egen räkning och på eget ansvar, inte för den ursprunglige licensgivarens eller någon annan bidragslämnares räkning, och endast om du förbinder dig att gottgöra och försvara och hålla varje bidragslämnare skadeslös, med avseende på ansvar som kan uppkomma eller krav som kan göras gällande mot denne bidragslämnare på grund av att du godtagit en garanti eller ett tilläggsansvar. + +10.Godkännande av licensen +Du godkänner villkoren i denna licens genom att klicka på ikonen ”Jag godkänner” som finns längst ner i ett fönster som visar licenstexten eller genom att bekräfta samtycke på annat liknande sätt, i enlighet med bestämmelserna i gällande lagstiftning. Genom att klicka på ikonen godkänner du entydigt och oåterkalleligt licensen och samtliga villkor i denna. På motsvarande sätt godkänner du oåterkalleligt denna licens och villkoren i densamma genom att utöva någon av de rättigheter som du tillerkänns genom punkt 2 i licensen, såsom att använda verket, skapa dina egna härledda verk eller genom att du sprider eller kommunicerar verket eller kopior av detta. + +11.Information till allmänheten +Om du sprider och/eller kommunicerar verket på elektronisk väg (exempelvis genom att erbjuda nedladdning av verket på distans) ska du via distributionskanalen eller mediet (exempelvis en webbplats) som ett minimum tillhandahålla allmänheten de uppgifter som krävs enligt tillämplig lag om licensgivaren, licensen och hur licenstagaren ska gå till väga för att få tillgång till, slutföra, lagra och mångfaldiga verket. + +12.Licensens upphörande +Licensen och rättigheterna enligt denna upphör automatiskt att gälla om licenstagaren bryter mot villkoren i licensen. Det faktum att licensen således upphör kommer inte att medföra att licenser som innehas av en person som tagit emot verket från licensinnehavaren enligt licensen upphör att gälla, förutsatt att dessa personer fortsättningsvis till fullo följer licensvillkoren. + +13.Övrigt +Licensen utgör, utan att det påverkar tillämpningen av punkt 9, det fullständiga avtalet mellan parterna med avseende på verket. Om någon bestämmelse i licensen är ogiltig eller icke är möjlig att verkställa enligt tillämplig lag, påverkar detta inte giltigheten eller verkställbarheten av licensen som helhet. En sådan bestämmelse kommer att tolkas eller ändras på det sätt som krävs för att den ska bli giltig och verkställbar. Europeiska kommissionen har rätt att offentliggöra andra språkversioner eller nya versioner av licensen, eller uppdaterade versioner av tillägget, i den mån det är nödvändigt och skäligt, utan att inskränka räckvidden av de rättigheter som beviljas enligt licensen. Nya versioner av licensen kommer att offentliggöras med ett unikt versionsnummer. Alla språkversioner av licensen som Europeiska kommissionen godkänt är likvärdiga. Parterna kan fritt välja vilken språkversion de vill utnyttja. + +14.Jurisdiktion +Utan att det påverkar tillämpningen av specifika avtal mellan parterna gäller följande: +— Eventuella tvister till följd av tolkningen av licensen som uppkommer mellan Europeiska unionens institutioner, organ, kontor eller myndigheter, i egenskap av licensgivare, och en licenstagare, kommer att underställas Europeiska unionens domstols behörighet i enlighet med artikel 272 i fördraget om Europeiska unionens funktionssätt. +— Eventuella tvister som uppkommer mellan andra parter och som följer av tolkningen av licensen, kommer att underställas exklusiv behörighet för den domstol som är behörig på den ort där licensgivaren är bosatt eller bedriver sin huvudsakliga verksamhet. + +15.Tillämplig lag +Utan att det påverkar tillämpningen av specifika avtal mellan parterna gäller följande: +— Licensen ska omfattas av lagstiftningen i den medlemsstat i Europeiska unionen där licensgivaren har sitt säte, är bosatt eller har sitt huvudkontor. +— Licensen ska omfattas av belgisk lagstiftning om licensgivaren inte har sitt säte, är bosatt eller har sitt huvudkontor i en av Europeiska unionens medlemsstater. + + +Tillägg +”Kompatibla licenser” enligt punkt 5 EUPL är följande: +— GNU General Public License (GPL) v. 2, v. 3. +— GNU Affero General Public License (AGPL) v. 3. +— Open Software License (OSL) v. 2.1, v. 3.0. +— Eclipse Public License (EPL) v. 1.0. +— CeCILL v. 2.0, v. 2.1. +— Mozilla Public Licence (MPL) v. 2. +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3. +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) för andra verk än programvara. +— European Union Public Licence (EUPL) v. 1.1, v. 1.2. +— Québec Free and Open-Source Licence – Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+). +Europeiska kommissionen får uppdatera detta tillägg med senare versioner av ovannämnda licenser utan att ta fram en ny version av EUPL, så länge som kommissionen tillhandahåller de rättigheter som beviljas i punkt 2 i denna licens och skyddar den källkod som omfattas från exklusiv rätt. +För alla andra ändringar i eller tillägg till detta tillägg krävs att en ny EUPL-version tas fram. diff --git a/vendor/FeldarianBaseLibrary/LICENSE.md b/vendor/FeldarianBaseLibrary/LICENSE.md new file mode 100644 index 0000000..4153cd3 --- /dev/null +++ b/vendor/FeldarianBaseLibrary/LICENSE.md @@ -0,0 +1,287 @@ + EUROPEAN UNION PUBLIC LICENCE v. 1.2 + EUPL © the European Union 2007, 2016 + +This European Union Public Licence (the ‘EUPL’) applies to the Work (as defined +below) which is provided under the terms of this Licence. Any use of the Work, +other than as authorised under this Licence is prohibited (to the extent such +use is covered by a right of the copyright holder of the Work). + +The Work is provided under the terms of this Licence when the Licensor (as +defined below) has placed the following notice immediately following the +copyright notice for the Work: + + Licensed under the EUPL + +or has expressed by any other means his willingness to license under the EUPL. + +1. Definitions + +In this Licence, the following terms have the following meaning: + +- ‘The Licence’: this Licence. + +- ‘The Original Work’: the work or software distributed or communicated by the + Licensor under this Licence, available as Source Code and also as Executable + Code as the case may be. + +- ‘Derivative Works’: the works or software that could be created by the + Licensee, based upon the Original Work or modifications thereof. This Licence + does not define the extent of modification or dependence on the Original Work + required in order to classify a work as a Derivative Work; this extent is + determined by copyright law applicable in the country mentioned in Article 15. + +- ‘The Work’: the Original Work or its Derivative Works. + +- ‘The Source Code’: the human-readable form of the Work which is the most + convenient for people to study and modify. + +- ‘The Executable Code’: any code which has generally been compiled and which is + meant to be interpreted by a computer as a program. + +- ‘The Licensor’: the natural or legal person that distributes or communicates + the Work under the Licence. + +- ‘Contributor(s)’: any natural or legal person who modifies the Work under the + Licence, or otherwise contributes to the creation of a Derivative Work. + +- ‘The Licensee’ or ‘You’: any natural or legal person who makes any usage of + the Work under the terms of the Licence. + +- ‘Distribution’ or ‘Communication’: any act of selling, giving, lending, + renting, distributing, communicating, transmitting, or otherwise making + available, online or offline, copies of the Work or providing access to its + essential functionalities at the disposal of any other natural or legal + person. + +2. Scope of the rights granted by the Licence + +The Licensor hereby grants You a worldwide, royalty-free, non-exclusive, +sublicensable licence to do the following, for the duration of copyright vested +in the Original Work: + +- use the Work in any circumstance and for all usage, +- reproduce the Work, +- modify the Work, and make Derivative Works based upon the Work, +- communicate to the public, including the right to make available or display + the Work or copies thereof to the public and perform publicly, as the case may + be, the Work, +- distribute the Work or copies thereof, +- lend and rent the Work or copies thereof, +- sublicense rights in the Work or copies thereof. + +Those rights can be exercised on any media, supports and formats, whether now +known or later invented, as far as the applicable law permits so. + +In the countries where moral rights apply, the Licensor waives his right to +exercise his moral right to the extent allowed by law in order to make effective +the licence of the economic rights here above listed. + +The Licensor grants to the Licensee royalty-free, non-exclusive usage rights to +any patents held by the Licensor, to the extent necessary to make use of the +rights granted on the Work under this Licence. + +3. Communication of the Source Code + +The Licensor may provide the Work either in its Source Code form, or as +Executable Code. If the Work is provided as Executable Code, the Licensor +provides in addition a machine-readable copy of the Source Code of the Work +along with each copy of the Work that the Licensor distributes or indicates, in +a notice following the copyright notice attached to the Work, a repository where +the Source Code is easily and freely accessible for as long as the Licensor +continues to distribute or communicate the Work. + +4. Limitations on copyright + +Nothing in this Licence is intended to deprive the Licensee of the benefits from +any exception or limitation to the exclusive rights of the rights owners in the +Work, of the exhaustion of those rights or of other applicable limitations +thereto. + +5. Obligations of the Licensee + +The grant of the rights mentioned above is subject to some restrictions and +obligations imposed on the Licensee. Those obligations are the following: + +Attribution right: The Licensee shall keep intact all copyright, patent or +trademarks notices and all notices that refer to the Licence and to the +disclaimer of warranties. The Licensee must include a copy of such notices and a +copy of the Licence with every copy of the Work he/she distributes or +communicates. The Licensee must cause any Derivative Work to carry prominent +notices stating that the Work has been modified and the date of modification. + +Copyleft clause: If the Licensee distributes or communicates copies of the +Original Works or Derivative Works, this Distribution or Communication will be +done under the terms of this Licence or of a later version of this Licence +unless the Original Work is expressly distributed only under this version of the +Licence — for example by communicating ‘EUPL v. 1.2 only’. The Licensee +(becoming Licensor) cannot offer or impose any additional terms or conditions on +the Work or Derivative Work that alter or restrict the terms of the Licence. + +Compatibility clause: If the Licensee Distributes or Communicates Derivative +Works or copies thereof based upon both the Work and another work licensed under +a Compatible Licence, this Distribution or Communication can be done under the +terms of this Compatible Licence. For the sake of this clause, ‘Compatible +Licence’ refers to the licences listed in the appendix attached to this Licence. +Should the Licensee's obligations under the Compatible Licence conflict with +his/her obligations under this Licence, the obligations of the Compatible +Licence shall prevail. + +Provision of Source Code: When distributing or communicating copies of the Work, +the Licensee will provide a machine-readable copy of the Source Code or indicate +a repository where this Source will be easily and freely available for as long +as the Licensee continues to distribute or communicate the Work. + +Legal Protection: This Licence does not grant permission to use the trade names, +trademarks, service marks, or 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 copyright notice. + +6. Chain of Authorship + +The original Licensor warrants that the copyright in the Original Work granted +hereunder is owned by him/her or licensed to him/her and that he/she has the +power and authority to grant the Licence. + +Each Contributor warrants that the copyright in the modifications he/she brings +to the Work are owned by him/her or licensed to him/her and that he/she has the +power and authority to grant the Licence. + +Each time You accept the Licence, the original Licensor and subsequent +Contributors grant You a licence to their contributions to the Work, under the +terms of this Licence. + +7. Disclaimer of Warranty + +The Work is a work in progress, which is continuously improved by numerous +Contributors. It is not a finished work and may therefore contain defects or +‘bugs’ inherent to this type of development. + +For the above reason, the Work is provided under the Licence on an ‘as is’ basis +and without warranties of any kind concerning the Work, including without +limitation merchantability, fitness for a particular purpose, absence of defects +or errors, accuracy, non-infringement of intellectual property rights other than +copyright as stated in Article 6 of this Licence. + +This disclaimer of warranty is an essential part of the Licence and a condition +for the grant of any rights to the Work. + +8. Disclaimer of Liability + +Except in the cases of wilful misconduct or damages directly caused to natural +persons, the Licensor will in no event be liable for any direct or indirect, +material or moral, damages of any kind, arising out of the Licence or of the use +of the Work, including without limitation, damages for loss of goodwill, work +stoppage, computer failure or malfunction, loss of data or any commercial +damage, even if the Licensor has been advised of the possibility of such damage. +However, the Licensor will be liable under statutory product liability laws as +far such laws apply to the Work. + +9. Additional agreements + +While distributing the Work, You may choose to conclude an additional agreement, +defining obligations or services consistent with this Licence. However, if +accepting obligations, You may act only on your own behalf and on your sole +responsibility, not on behalf of the original Licensor or 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 +the fact You have accepted any warranty or additional liability. + +10. Acceptance of the Licence + +The provisions of this Licence can be accepted by clicking on an icon ‘I agree’ +placed under the bottom of a window displaying the text of this Licence or by +affirming consent in any other similar way, in accordance with the rules of +applicable law. Clicking on that icon indicates your clear and irrevocable +acceptance of this Licence and all of its terms and conditions. + +Similarly, you irrevocably accept this Licence and all of its terms and +conditions by exercising any rights granted to You by Article 2 of this Licence, +such as the use of the Work, the creation by You of a Derivative Work or the +Distribution or Communication by You of the Work or copies thereof. + +11. Information to the public + +In case of any Distribution or Communication of the Work by means of electronic +communication by You (for example, by offering to download the Work from a +remote location) the distribution channel or media (for example, a website) must +at least provide to the public the information requested by the applicable law +regarding the Licensor, the Licence and the way it may be accessible, concluded, +stored and reproduced by the Licensee. + +12. Termination of the Licence + +The Licence and the rights granted hereunder will terminate automatically upon +any breach by the Licensee of the terms of the Licence. + +Such a termination will not terminate the licences of any person who has +received the Work from the Licensee under the Licence, provided such persons +remain in full compliance with the Licence. + +13. Miscellaneous + +Without prejudice of Article 9 above, the Licence represents the complete +agreement between the Parties as to the Work. + +If any provision of the Licence is invalid or unenforceable under applicable +law, this will not affect the validity or enforceability of the Licence as a +whole. Such provision will be construed or reformed so as necessary to make it +valid and enforceable. + +The European Commission may publish other linguistic versions or new versions of +this Licence or updated versions of the Appendix, so far this is required and +reasonable, without reducing the scope of the rights granted by the Licence. New +versions of the Licence will be published with a unique version number. + +All linguistic versions of this Licence, approved by the European Commission, +have identical value. Parties can take advantage of the linguistic version of +their choice. + +14. Jurisdiction + +Without prejudice to specific agreement between parties, + +- any litigation resulting from the interpretation of this License, arising + between the European Union institutions, bodies, offices or agencies, as a + Licensor, and any Licensee, will be subject to the jurisdiction of the Court + of Justice of the European Union, as laid down in article 272 of the Treaty on + the Functioning of the European Union, + +- any litigation arising between other parties and resulting from the + interpretation of this License, will be subject to the exclusive jurisdiction + of the competent court where the Licensor resides or conducts its primary + business. + +15. Applicable Law + +Without prejudice to specific agreement between parties, + +- this Licence shall be governed by the law of the European Union Member State + where the Licensor has his seat, resides or has his registered office, + +- this licence shall be governed by Belgian law if the Licensor has no seat, + residence or registered office inside a European Union Member State. + +Appendix + +‘Compatible Licences’ according to Article 5 EUPL are: + +- GNU General Public License (GPL) v. 2, v. 3 +- GNU Affero General Public License (AGPL) v. 3 +- Open Software License (OSL) v. 2.1, v. 3.0 +- Eclipse Public License (EPL) v. 1.0 +- CeCILL v. 2.0, v. 2.1 +- Mozilla Public Licence (MPL) v. 2 +- GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +- Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for + works other than software +- European Union Public Licence (EUPL) v. 1.1, v. 1.2 +- Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong + Reciprocity (LiLiQ-R+). + +The European Commission may update this Appendix to later versions of the above +licences without producing a new version of the EUPL, as long as they provide +the rights granted in Article 2 of this Licence and protect the covered Source +Code from exclusive appropriation. + +All other changes or additions to this Appendix require the production of a new +EUPL version. diff --git a/vendor/FeldarianBaseLibrary/LICENSE_ThirdParty.md b/vendor/FeldarianBaseLibrary/LICENSE_ThirdParty.md new file mode 100644 index 0000000..d1ebdc3 --- /dev/null +++ b/vendor/FeldarianBaseLibrary/LICENSE_ThirdParty.md @@ -0,0 +1,603 @@ +# adpcm-xq + Copyright (c) David Bryant + All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Conifer Software 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. + +# libsamplerate +Copyright (c) 2012-2016, Erik de Castro Lopo +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 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 +HOLDER 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. + +# libsndfile + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + +# toml++ +MIT License + +Copyright (c) Mark Gillard + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +# xxhash +xxHash Library +Copyright (c) 2012-2021 Yann Collet +All rights reserved. + +BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) + +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, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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/vendor/FeldarianBaseLibrary/README.md b/vendor/FeldarianBaseLibrary/README.md new file mode 100644 index 0000000..29cf349 --- /dev/null +++ b/vendor/FeldarianBaseLibrary/README.md @@ -0,0 +1,12 @@ +# Feldarian Base Library + +This is base library used in Feldarian projects. +It contains only selected parts of it required for other public tools to compile. +Public release contains following interfaces: + * UTF - helpers providing facilities to ease work with UTF conversions, localization and required glyph caching. + * PCMS16 - helper providing facilities to convert to and from WAV PCM S16 format. + +## Used "Open-Source Licensed" Tools + * [PVS-Studio](https://pvs-studio.com/en/pvs-studio/?utm_source=website&utm_medium=github&utm_campaign=open_source) - static analyzer for C, C++, C#, and Java code. + * [ReSharper C++](https://www.jetbrains.com/community/opensource/#support) - provides multiple features for increasing productivity when working with C++ code. + * [SmartGit](https://www.syntevo.com/register-non-commercial/) - cross-platform Git GUI client. diff --git a/vendor/FeldarianBaseLibrary/include/Feldarian/PCMS16/PCMS16.hpp b/vendor/FeldarianBaseLibrary/include/Feldarian/PCMS16/PCMS16.hpp new file mode 100644 index 0000000..f51adbf --- /dev/null +++ b/vendor/FeldarianBaseLibrary/include/Feldarian/PCMS16/PCMS16.hpp @@ -0,0 +1,150 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 +// + +#pragma once + +#include +#include +#include + +#define PCMS16_CONVERSION_FLAG_RAW_OUTPUT 0x01 +#define PCMS16_CONVERSION_FLAG_ADPCM_DISABLE_NOISE_SHAPING 0x02 + +struct PCMS16_Header +{ + char riffId[4] = {'R', 'I', 'F', 'F'}; + uint32_t riffSize = 0x24; + char waveId[4] = {'W', 'A', 'V', 'E'}; + char fmtId[4] = {'f', 'm', 't', ' '}; + uint32_t fmtSize = 0x10; + uint16_t fmtFormat = 0x01; + uint16_t fmtChannels = 0; + uint32_t fmtSampleRate = 0; + uint32_t fmtAvgBytesRate = 0; + uint16_t fmtBlockAlign = 0; + uint16_t fmtBitsPerSample = 0; + char dataId[4] = {'d', 'a', 't', 'a'}; + uint32_t dataSize = 0; +}; + +struct ADPCM_Header +{ + char riffId[4] = {'R', 'I', 'F', 'F'}; + uint32_t riffSize = 0x34; + char waveId[4] = {'W', 'A', 'V', 'E'}; + char fmtId[4] = {'f', 'm', 't', ' '}; + uint32_t fmtSize = 0x14; + uint16_t fmtFormat = 0x11; + uint16_t fmtChannels = 0; + uint32_t fmtSampleRate = 0; + uint32_t fmtAvgBytesRate = 0; + uint16_t fmtBlockAlign = 0; + uint16_t fmtBitsPerSample = 0; + uint16_t fmtExtraSize = 0x02; + uint16_t fmtExtraSamplesPerBlock = 0x3F9; + char factId[4] = {'f', 'a', 'c', 't'}; + uint32_t factSize = 0x04; + uint32_t factSamplesCount = 0; + char dataId[4] = {'d', 'a', 't', 'a'}; + uint32_t dataSize = 0; +}; + +struct SoundRecord +{ + uint64_t dataXXH3 = 0; + uint32_t dataSizeUncompressed = 0; + uint32_t dataSize = 0; + uint32_t sampleRate = 0; + uint16_t formatTag = 0; + uint16_t bitsPerSample = 0; + uint16_t channels = 0; + uint16_t blockAlign = 0; + uint16_t samplesPerBlock = 0; + + auto operator<=>(const SoundRecord & other) const = default; +}; + +PCMS16_Header PCMS16Header(const SoundRecord& record); +PCMS16_Header PCMS16Header(const std::span& in); + +SoundRecord PCMS16SoundRecord(const PCMS16_Header& header, uint64_t xxh3Hash = 0); +SoundRecord PCMS16SoundRecord(const PCMS16_Header& header, const std::span& in); +SoundRecord PCMS16SoundRecord(const std::span& in); + +std::span PCMS16DataView(const PCMS16_Header& header, const std::span& in); +std::span PCMS16DataView(const std::span& in); + +ADPCM_Header ADPCMHeader(const SoundRecord& record, int blocksizePow2 = 0); +ADPCM_Header ADPCMHeader(const std::span& in); + +SoundRecord ADPCMSoundRecord(const ADPCM_Header& header, uint64_t xxh3Hash = 0); +SoundRecord ADPCMSoundRecord(const ADPCM_Header& header, const std::span& in, bool pcms16XXH3Hash = true); +SoundRecord ADPCMSoundRecord(const std::span& in); + +std::span ADPCMDataView(const ADPCM_Header& header, const std::span& in); +std::span ADPCMDataView(const std::span& in); + +SoundRecord VorbisHeader(const std::span& in); + +SoundRecord VorbisSoundRecord(const SoundRecord& header, uint64_t xxh3Hash = 0); +SoundRecord VorbisSoundRecord(const SoundRecord& header, const std::span& in, bool pcms16XXH3Hash = true); +SoundRecord VorbisSoundRecord(const std::span& in); + +std::span VorbisDataView(const SoundRecord& header, const std::span& in); +std::span VorbisDataView(const std::span& in); + +SoundRecord UnknownSoundDataHeader(const std::span& in); + +SoundRecord UnknownSoundDataSoundRecord(const SoundRecord& header, uint64_t xxh3Hash = 0); +SoundRecord UnknownSoundDataSoundRecord(const SoundRecord& header, const std::span& in, bool pcms16XXH3Hash = true); +SoundRecord UnknownSoundDataSoundRecord(const std::span& in); + +std::span UnknownSoundDataDataView(const SoundRecord& header, const std::span& in); +std::span UnknownSoundDataDataView(const std::span& in); + +SoundRecord SoundDataHeader(const std::span& in); + +SoundRecord SoundDataSoundRecord(const SoundRecord& header, uint64_t xxh3Hash = 0); +SoundRecord SoundDataSoundRecord(const SoundRecord& header, const std::span& in, bool pcms16XXH3Hash = true); +SoundRecord SoundDataSoundRecord(const std::span& in); + +std::span SoundDataDataView(const SoundRecord& header, const std::span& in); +std::span SoundDataDataView(const std::span& in); + +int32_t PCMS16ChangeSampleRate(PCMS16_Header& header, std::vector& data, uint32_t newSampleRate); +int32_t PCMS16ChangeSampleRate(PCMS16_Header& header, std::vector& data, uint32_t newSampleRate); + +int32_t PCMS16ChangeChannelCount(PCMS16_Header& header, std::vector& data, uint16_t newChannelCount); +int32_t PCMS16ChangeChannelCount(PCMS16_Header& header, std::vector& data, uint16_t newChannelCount); + +bool PCMS16FromADPCM(const ADPCM_Header &header, const std::span& in, std::vector &out, int flags = 0); +bool PCMS16FromADPCM(const std::span& in, std::vector &out, int flags = 0); + +bool PCMS16FromVorbis(const SoundRecord &header, const std::span& in, std::vector &out, int flags = 0); +bool PCMS16FromVorbis(const std::span& in, std::vector &out, int flags = 0); + +bool PCMS16FromUnknownSoundData(const SoundRecord &header, const std::span& in, std::vector &out, int flags = 0); +bool PCMS16FromUnknownSoundData(const std::span& in, std::vector &out, int flags = 0); + +bool PCMS16FromSoundData(const SoundRecord &header, const std::span& in, std::vector &out, int flags = 0); +bool PCMS16FromSoundData(const std::span& in, std::vector &out, int flags = 0); + +bool PCMS16ToADPCM(const PCMS16_Header& header, const std::span& in, std::vector &out, int flags = 0, int blocksizePow2 = 0, int lookahead = 3); +bool PCMS16ToADPCM(const std::span& in, std::vector &out, int flags = 0, int blocksizePow2 = 0, int lookahead = 3); + +bool PCMS16ToVorbis(const PCMS16_Header& header, const std::span& in, std::vector &out, int flags = 0); +bool PCMS16ToVorbis(const std::span& in, std::vector &out, int flags = 0); + +template +requires std::is_pod_v && std::is_pod_v && (std::is_const_v || !std::is_const_v) +std::span ToSpan(const std::span& in) +{ + const auto byteSize = (in.size() * sizeof(InputSpanType)); + if (byteSize % sizeof(OutputSpanType)) + return {}; + + return {reinterpret_cast(in.data()), byteSize / sizeof(OutputSpanType)}; +} diff --git a/src/UTF/Common.hpp b/vendor/FeldarianBaseLibrary/include/Feldarian/UTF/Common.hpp similarity index 66% rename from src/UTF/Common.hpp rename to vendor/FeldarianBaseLibrary/include/Feldarian/UTF/Common.hpp index afa8e4d..d901f93 100644 --- a/src/UTF/Common.hpp +++ b/vendor/FeldarianBaseLibrary/include/Feldarian/UTF/Common.hpp @@ -6,6 +6,25 @@ #pragma once +// TODO - these should not be in the header! including ICU... +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + namespace UTF { @@ -53,3 +72,12 @@ static constexpr auto CodepointInvalid{ 0ul }; static constexpr auto CodepointMax{ 0x10FFFFul }; } + +template , typename AllocatorType = std::allocator>> +using OrderedMap = std::map; + +template , typename AllocatorType = std::allocator> +using OrderedSet = std::set; + +template +using OptionalReference = std::optional>; diff --git a/src/UTF/GlyphRangesBuilder.hpp b/vendor/FeldarianBaseLibrary/include/Feldarian/UTF/GlyphRangesBuilder.hpp similarity index 91% rename from src/UTF/GlyphRangesBuilder.hpp rename to vendor/FeldarianBaseLibrary/include/Feldarian/UTF/GlyphRangesBuilder.hpp index 5d8ff71..83b3722 100644 --- a/src/UTF/GlyphRangesBuilder.hpp +++ b/vendor/FeldarianBaseLibrary/include/Feldarian/UTF/GlyphRangesBuilder.hpp @@ -6,10 +6,12 @@ #pragma once +#include "Common.hpp" + namespace UTF { -class GlyphRangesBuilder : public Singleton +class GlyphRangesBuilder { public: @@ -34,7 +36,7 @@ class GlyphRangesBuilder : public Singleton { std::vector> glyphRanges; - std::lock_guard lock(dataMutex); + std::lock_guard writeLock(dataMutex); std::pair glyphRange{CodepointInvalid, CodepointInvalid}; for (uint32_t glyph = 1; glyph <= CodepointMax; ++glyph) @@ -74,9 +76,15 @@ class GlyphRangesBuilder : public Singleton if (glyph == CodepointInvalid || glyph > CodepointMax) return; - std::lock_guard lock(dataMutex); - newGlyphsAdded |= !glyphsInUse.test(glyph); + { + std::shared_lock readLock(dataMutex); + if (glyphsInUse.test(glyph)) + return; + } + + std::lock_guard writeLock(dataMutex); glyphsInUse.set(glyph); + newGlyphsAdded = true; } template > @@ -142,7 +150,7 @@ class GlyphRangesBuilder : public Singleton std::bitset glyphsInUse; bool newGlyphsAdded = false; - mutable std::mutex dataMutex; + mutable std::shared_mutex dataMutex; }; } diff --git a/src/UTF/Localization.hpp b/vendor/FeldarianBaseLibrary/include/Feldarian/UTF/Localization.hpp similarity index 79% rename from src/UTF/Localization.hpp rename to vendor/FeldarianBaseLibrary/include/Feldarian/UTF/Localization.hpp index f61cbcf..c60112f 100644 --- a/src/UTF/Localization.hpp +++ b/vendor/FeldarianBaseLibrary/include/Feldarian/UTF/Localization.hpp @@ -6,6 +6,10 @@ #pragma once +#include "Common.hpp" + +#include "GlyphRangesBuilder.hpp" + namespace UTF { @@ -14,6 +18,10 @@ class LocalizationInstance public: inline static const String8 Empty; + LocalizationInstance(GlyphRangesBuilder& glyphRangesBuilder) + : glyphRangesBuilder(glyphRangesBuilder) + { } + void Clear() { localizationMap.clear(); @@ -34,8 +42,8 @@ class LocalizationInstance String8CI keyUTF{key.str()}; String8 valueUTF{**value.as_string()}; - GlyphRangesBuilder::Get().AddText(keyUTF); - GlyphRangesBuilder::Get().AddText(valueUTF); + glyphRangesBuilder.AddText(keyUTF); + glyphRangesBuilder.AddText(valueUTF); localizationMap.insert_or_assign(std::move(keyUTF), std::move(valueUTF)); } @@ -76,11 +84,16 @@ class LocalizationInstance private: OrderedMap localizationMap; + GlyphRangesBuilder& glyphRangesBuilder; }; -class LocalizationManager : public Singleton +class LocalizationManager { public: + LocalizationManager(GlyphRangesBuilder& glyphRangesBuilder) + : glyphRangesBuilder(glyphRangesBuilder) + { } + bool LoadLocalization(const StringView8CI &localizationPathView) { const auto localizationPath = localizationPathView.path(); @@ -107,7 +120,7 @@ class LocalizationManager : public Singleton if (languageName.empty()) return false; - GlyphRangesBuilder::Get().AddText(languageName); + glyphRangesBuilder.AddText(languageName); const auto localizationTableValue = localizationFile["localization"]; if (!localizationTableValue.is_table()) @@ -118,16 +131,13 @@ class LocalizationManager : public Singleton std::lock_guard lock(dataMutex); const auto [localizationInstanceIt, localizationInstanceEmplaced] = - localizationInstancesMap.try_emplace(languageName, LocalizationInstance{}); + localizationInstancesMap.try_emplace(languageName, LocalizationInstance{glyphRangesBuilder}); const auto localizationLoaded = localizationInstanceIt->second.Load(localizationTable); if (localizationInstanceEmplaced) { if (!localizationLoaded) localizationInstancesMap.erase(localizationInstanceIt); - - SetDefaultLanguage(defaultLocalizationLanguage); - SetLanguage(localizationLanguage); } return localizationLoaded; @@ -157,7 +167,7 @@ class LocalizationManager : public Singleton return true; } - const String8CI &GetDefaultLanguage() const + String8CI GetDefaultLanguage() const { std::shared_lock lock(dataMutex); @@ -180,47 +190,46 @@ class LocalizationManager : public Singleton return true; } - const String8CI &GetLanguage() const + String8CI GetLanguage() const { std::shared_lock lock(dataMutex); - return localizationLanguage.empty() ? GetDefaultLanguage() : localizationLanguage; + return localizationLanguage.empty() ? defaultLocalizationLanguage : localizationLanguage; } template requires StringViewConstructible - const String8 &Localize(const Args &...args) const + String8 Localize(const Args &...args) const { std::shared_lock lock(dataMutex); - - const auto &localized = - localizationInstance ? localizationInstance->Localize(args...) : LocalizationInstance::Empty; - if (!localized.empty()) - return localized; - - return defaultLocalizationInstance ? defaultLocalizationInstance->Localize(args...) : LocalizationInstance::Empty; + const auto& localized = LocalizeInternal(args...); + return localized.empty() ? String8(args...) : localized; } template requires StringViewConstructible String8 &LocalizeFormatTo(String8 &buffer, const Type &key, FormatArgs &&...args) const { - std::shared_lock lock(dataMutex); - buffer.clear(); - const auto &localizedFormat = Localize(key); + std::shared_lock lock(dataMutex); + + const auto &localizedFormat = LocalizeInternal(key); if (localizedFormat.empty()) - return buffer; + return buffer = key; try { std::vformat_to(std::back_inserter(buffer.native()), localizedFormat.native(), std::make_format_args(std::forward(args)...)); } - catch (std::format_error &) + //catch (std::format_error &) + //{ + // return buffer = key; + //} + catch (...) { - buffer.clear(); + return buffer = key; } return buffer; @@ -236,13 +245,34 @@ class LocalizationManager : public Singleton } private: + + template + requires StringViewConstructible + const String8 &LocalizeInternal(const Args &...args) const + { + const auto &localized = + localizationInstance ? localizationInstance->Localize(args...) : LocalizationInstance::Empty; + if (!localized.empty()) + return localized; + + const auto &defaultLocalized = + defaultLocalizationInstance ? defaultLocalizationInstance->Localize(args...) : LocalizationInstance::Empty; + if (!defaultLocalized.empty()) + return defaultLocalized; + + assert(!defaultLocalized.empty()); + return LocalizationInstance::Empty; + } + OrderedMap> localizationInstancesMap; - String8CI defaultLocalizationLanguage; + StringView8CI defaultLocalizationLanguage; LocalizationInstance *defaultLocalizationInstance = nullptr; - String8CI localizationLanguage; + StringView8CI localizationLanguage; LocalizationInstance *localizationInstance = nullptr; mutable std::shared_mutex dataMutex; + + GlyphRangesBuilder& glyphRangesBuilder; }; } // namespace UTF diff --git a/src/UTF/String.hpp b/vendor/FeldarianBaseLibrary/include/Feldarian/UTF/String.hpp similarity index 99% rename from src/UTF/String.hpp rename to vendor/FeldarianBaseLibrary/include/Feldarian/UTF/String.hpp index d26062f..14a8f33 100644 --- a/src/UTF/String.hpp +++ b/vendor/FeldarianBaseLibrary/include/Feldarian/UTF/String.hpp @@ -6,6 +6,8 @@ #pragma once +#include "Common.hpp" + #include "Strings-impl/StringViewWrapper-declarations.hpp" #include "Strings-impl/StringWrapper-declarations.hpp" diff --git a/src/UTF/Strings-impl/StringViewWrapper-declarations.hpp b/vendor/FeldarianBaseLibrary/include/Feldarian/UTF/Strings-impl/StringViewWrapper-declarations.hpp similarity index 100% rename from src/UTF/Strings-impl/StringViewWrapper-declarations.hpp rename to vendor/FeldarianBaseLibrary/include/Feldarian/UTF/Strings-impl/StringViewWrapper-declarations.hpp diff --git a/src/UTF/Strings-impl/StringViewWrapper-definitions.hpp b/vendor/FeldarianBaseLibrary/include/Feldarian/UTF/Strings-impl/StringViewWrapper-definitions.hpp similarity index 100% rename from src/UTF/Strings-impl/StringViewWrapper-definitions.hpp rename to vendor/FeldarianBaseLibrary/include/Feldarian/UTF/Strings-impl/StringViewWrapper-definitions.hpp diff --git a/src/UTF/Strings-impl/StringWrapper-declarations.hpp b/vendor/FeldarianBaseLibrary/include/Feldarian/UTF/Strings-impl/StringWrapper-declarations.hpp similarity index 100% rename from src/UTF/Strings-impl/StringWrapper-declarations.hpp rename to vendor/FeldarianBaseLibrary/include/Feldarian/UTF/Strings-impl/StringWrapper-declarations.hpp diff --git a/src/UTF/Strings-impl/StringWrapper-definitions.hpp b/vendor/FeldarianBaseLibrary/include/Feldarian/UTF/Strings-impl/StringWrapper-definitions.hpp similarity index 100% rename from src/UTF/Strings-impl/StringWrapper-definitions.hpp rename to vendor/FeldarianBaseLibrary/include/Feldarian/UTF/Strings-impl/StringWrapper-definitions.hpp diff --git a/src/UTF/UTF.hpp b/vendor/FeldarianBaseLibrary/include/Feldarian/UTF/UTF.hpp similarity index 100% rename from src/UTF/UTF.hpp rename to vendor/FeldarianBaseLibrary/include/Feldarian/UTF/UTF.hpp diff --git a/vendor/FeldarianBaseLibrary/src/PCMS16/PCMS16.cpp b/vendor/FeldarianBaseLibrary/src/PCMS16/PCMS16.cpp new file mode 100644 index 0000000..1a786ac --- /dev/null +++ b/vendor/FeldarianBaseLibrary/src/PCMS16/PCMS16.cpp @@ -0,0 +1,1426 @@ +// +// Created by Andrej Redeky. +// Copyright © 2015-2023 Feldarian Softworks. All rights reserved. +// SPDX-License-Identifier: EUPL-1.2 +// +// TODO - there are checks whether there is some data in header (dataSize != 0), but there are missing checks whether requested format matches! wrong header and data may be supplied! +// + +#include + +extern "C" +{ + +#if FBL_PCMS16_USE_ADPCMXQ +#include +#endif + +#include +#include +#include + +} + +#include + +#include +#include +#include + +namespace +{ + +struct SF_VIRTUAL_DATA_FIXED +{ + char* data = nullptr; + sf_count_t dataSize = 0; + sf_count_t offset = 0; +}; + +struct SF_VIRTUAL_DATA +{ + std::vector &data; + sf_count_t offset = 0; +}; + +SF_VIRTUAL_IO g_VirtSndFileIOFixed { + .get_filelen = [](void *user_data) -> sf_count_t { + const auto* virtData = static_cast(user_data); + return virtData->dataSize; + }, + .seek = [](const sf_count_t offset, const int whence, void *user_data) -> sf_count_t { + auto* virtData = static_cast(user_data); + + switch (whence) + { + case SEEK_SET: + virtData->offset = offset; + break; + + case SEEK_CUR: + virtData->offset += offset; + break; + + case SEEK_END: + virtData->offset = virtData->dataSize + offset; + break; + + default: + break; + } + + assert(virtData->offset <= virtData->dataSize); + return virtData->offset; + }, + .read = [](void *ptr, const sf_count_t count, void *user_data) -> sf_count_t { + auto* virtData = static_cast(user_data); + + const auto bytesToRead = std::min(virtData->dataSize - virtData->offset, count); + + memcpy(ptr, virtData->data + virtData->offset, bytesToRead); + virtData->offset += bytesToRead; + + return bytesToRead; + }, + .write = [](const void *ptr, const sf_count_t count, void *user_data) -> sf_count_t { + auto* virtData = static_cast(user_data); + + const auto bytesToWrite = std::min(virtData->dataSize - virtData->offset, count); + + memcpy(virtData->data + virtData->offset, ptr, bytesToWrite); + virtData->offset += bytesToWrite; + + return bytesToWrite; + }, + .tell = [](void *user_data) -> sf_count_t { + const auto* virtData = static_cast(user_data); + return virtData->offset; + }, +}; + +SF_VIRTUAL_IO g_VirtSndFileIO { + .get_filelen = [](void *user_data) -> sf_count_t { + const auto* virtData = static_cast(user_data); + return static_cast(virtData->data.size()); + }, + .seek = [](const sf_count_t offset, const int whence, void *user_data) -> sf_count_t { + auto* virtData = static_cast(user_data); + + switch (whence) + { + case SEEK_SET: + virtData->offset = offset; + break; + + case SEEK_CUR: + virtData->offset += offset; + break; + + case SEEK_END: + virtData->offset = virtData->data.size() + offset; + break; + + default: + break; + } + + assert(static_cast(virtData->offset) <= virtData->data.size()); + return virtData->offset; + }, + .read = [](void *ptr, const sf_count_t count, void *user_data) -> sf_count_t { + auto* virtData = static_cast(user_data); + + const auto bytesToRead = std::min(static_cast(virtData->data.size()) - virtData->offset, count); + + memcpy(ptr, virtData->data.data() + virtData->offset, bytesToRead); + virtData->offset += bytesToRead; + + return bytesToRead; + }, + .write = [](const void *ptr, const sf_count_t count, void *user_data) -> sf_count_t { + auto* virtData = static_cast(user_data); + + if (static_cast(virtData->data.size()) - virtData->offset < count) + virtData->data.resize(virtData->data.size() + count, 0); + + memcpy(virtData->data.data() + virtData->offset, ptr, count); + virtData->offset += count; + + return count; + }, + .tell = [](void *user_data) -> sf_count_t { + const auto* virtData = static_cast(user_data); + return virtData->offset; + }, +}; + +void PCMS16WriteHeader(std::vector &out, int num_channels, uint32_t num_samples, uint32_t sample_rate) +{ + const auto total_data_bytes = static_cast(num_samples * num_channels * sizeof(int16_t)); + + PCMS16_Header riffHeader; + riffHeader.riffSize += total_data_bytes; + riffHeader.fmtChannels = static_cast(num_channels); + riffHeader.fmtSampleRate = sample_rate; + riffHeader.fmtBlockAlign = static_cast(num_channels * sizeof(int16_t)); + riffHeader.fmtAvgBytesRate = sample_rate * riffHeader.fmtBlockAlign; + riffHeader.fmtBitsPerSample = 16; + riffHeader.dataSize = total_data_bytes; + + const auto outOffsetInput = out.size(); + out.resize(outOffsetInput + sizeof(PCMS16_Header) / sizeof(int16_t)); + std::memcpy(out.data() + outOffsetInput, &riffHeader, sizeof(PCMS16_Header)); +} + +#if FBL_PCMS16_USE_ADPCMXQ +void ADPCMWriteHeader(std::vector &out, uint16_t num_channels, uint32_t num_samples, uint32_t sample_rate, uint32_t samples_per_block) +{ + const auto block_size = (samples_per_block - 1) / (num_channels ^ 3) + (num_channels * 4); + const auto num_blocks = num_samples / samples_per_block; + const auto leftover_samples = num_samples % samples_per_block; + const auto total_data_bytes = (num_blocks + (leftover_samples != 0)) * block_size; + + ADPCM_Header riffHeader; + riffHeader.riffSize += total_data_bytes; + riffHeader.fmtChannels = num_channels; + riffHeader.fmtSampleRate = sample_rate; + riffHeader.fmtAvgBytesRate = sample_rate * block_size / samples_per_block; + riffHeader.fmtBlockAlign = block_size; + riffHeader.fmtBitsPerSample = 4; + riffHeader.fmtExtraSamplesPerBlock = samples_per_block; + riffHeader.dataSize = total_data_bytes; + + const auto outOffsetInput = out.size(); + out.resize(outOffsetInput + sizeof(ADPCM_Header)); + std::memcpy(out.data() + outOffsetInput, &riffHeader, sizeof(ADPCM_Header)); +} + +bool ADPCMDecodeData(const std::span& in, std::vector &out, uint16_t num_channels, uint32_t num_samples, uint16_t block_size) +{ + const auto samples_per_block = static_cast((block_size - num_channels * 4) * (num_channels ^ 3) + 1); + const auto total_data_shorts = num_samples * num_channels; + + thread_local static std::vector pcmBlock; + pcmBlock.resize(samples_per_block * num_channels); + + thread_local static std::vector adpcmBlock; + adpcmBlock.resize(block_size); + + const auto outOffsetInput = out.size(); + out.resize(outOffsetInput + total_data_shorts); + + size_t inOffset = 0; + auto outOffset = outOffsetInput; + while (num_samples) + { + auto this_block_adpcm_samples = samples_per_block; + auto this_block_pcm_samples = samples_per_block; + + if (this_block_adpcm_samples > num_samples) + { + this_block_adpcm_samples = ((num_samples + 6) & ~7) + 1; + block_size = (this_block_adpcm_samples - 1) / (num_channels ^ 3) + (num_channels * 4); + this_block_pcm_samples = num_samples; + } + + assert(inOffset + block_size <= in.size()); + std::ranges::fill(adpcmBlock, 0); + std::memcpy(adpcmBlock.data(), in.data() + inOffset, block_size); + + assert(outOffset + this_block_pcm_samples * num_channels <= out.size()); + std::ranges::fill(pcmBlock, 0); + + if (adpcm_decode_block(pcmBlock.data(), adpcmBlock.data(), block_size, num_channels) != this_block_adpcm_samples) + { + out.resize(outOffsetInput); + return false; + } + + std::memcpy(out.data() + outOffset, pcmBlock.data(), this_block_pcm_samples * num_channels * sizeof(int16_t)); + + inOffset += block_size; + outOffset += samples_per_block * num_channels; + + num_samples -= this_block_pcm_samples; + } + + return true; +} + +bool ADPCMEncodeData(const std::span& in, std::vector &out, uint16_t num_channels, uint32_t num_samples, uint16_t samples_per_block, int lookahead, int noise_shaping) +{ + auto block_size = (samples_per_block - 1) / (num_channels ^ 3) + (num_channels * 4); + const auto num_blocks = num_samples / samples_per_block; + const auto leftover_samples = num_samples % samples_per_block; + auto total_data_bytes = (num_blocks + (leftover_samples != 0)) * block_size; + + const auto outOffsetInput = out.size(); + out.resize(outOffsetInput + total_data_bytes); + + thread_local static std::vector pcmBlock; + pcmBlock.resize(samples_per_block * num_channels); + + thread_local static std::vector adpcmBlock; + adpcmBlock.resize(block_size); + + void *adpcm_cnxt = nullptr; + + size_t inOffset = 0; + auto outOffset = outOffsetInput; + while (num_samples) { + auto this_block_adpcm_samples = samples_per_block; + auto this_block_pcm_samples = samples_per_block; + + if (this_block_pcm_samples > num_samples) + { + this_block_adpcm_samples = ((num_samples + 6) & ~7) + 1; + block_size = (this_block_adpcm_samples - 1) / (num_channels ^ 3) + (num_channels * 4); + this_block_pcm_samples = num_samples; + } + + assert(inOffset + this_block_pcm_samples * num_channels <= in.size()); + std::ranges::fill(pcmBlock, 0); + std::memcpy(pcmBlock.data(), in.data() + inOffset, this_block_pcm_samples * num_channels * sizeof(int16_t)); + + if (this_block_adpcm_samples > this_block_pcm_samples) + { + int16_t *dst = pcmBlock.data() + this_block_pcm_samples * num_channels, *src = dst - num_channels; + int dups = (this_block_adpcm_samples - this_block_pcm_samples) * num_channels; + + while (dups--) + *dst++ = *src++; + } + + // if this is the first block, compute a decaying average (in reverse) so that we can let the + // encoder know what kind of initial deltas to expect (helps initializing index) + + if (!adpcm_cnxt) { + int32_t average_deltas [2]; + + average_deltas [0] = average_deltas [1] = 0; + + for (int i = this_block_adpcm_samples * num_channels; i -= num_channels;) { + average_deltas [0] -= average_deltas [0] >> 3; + average_deltas [0] += abs (static_cast(pcmBlock[i]) - pcmBlock[i - num_channels]); + + if (num_channels == 2) { + average_deltas [1] -= average_deltas [1] >> 3; + average_deltas [1] += abs (static_cast(pcmBlock[i - 1]) - pcmBlock[i+1]); + } + } + + average_deltas [0] >>= 3; + average_deltas [1] >>= 3; + + adpcm_cnxt = adpcm_create_context (num_channels, lookahead, noise_shaping, average_deltas); + } + + assert(outOffset + block_size <= out.size()); + std::ranges::fill(adpcmBlock, 0); + + size_t num_bytes; + adpcm_encode_block(adpcm_cnxt, adpcmBlock.data(), &num_bytes, pcmBlock.data(), this_block_adpcm_samples); + + if (num_bytes != block_size) + { + out.resize(outOffsetInput); + return false; + } + + std::memcpy(out.data() + outOffset, adpcmBlock.data(), block_size); + + inOffset += samples_per_block * num_channels; + outOffset += block_size; + + num_samples -= this_block_pcm_samples; + } + + if (adpcm_cnxt) + adpcm_free_context (adpcm_cnxt); + + return true; +} + +bool PCMS16FromADPCM_ADPCMXQ(const ADPCM_Header &header, const std::span &in, std::vector &out, int flags) +{ + if (!header.dataSize || in.size() < header.dataSize) + return false; + + const uint32_t complete_blocks = header.dataSize / header.fmtBlockAlign; + const int leftover_bytes = header.dataSize % header.fmtBlockAlign; + int samples_last_block; + + auto num_samples = complete_blocks * header.fmtExtraSamplesPerBlock; + + if (leftover_bytes) { + if (leftover_bytes % (header.fmtChannels * 4)) + return false; + + samples_last_block = (leftover_bytes - (header.fmtChannels * 4)) * (header.fmtChannels ^ 3) + 1; + num_samples += samples_last_block; + } + else + samples_last_block = header.fmtExtraSamplesPerBlock; + + if (const auto fact_samples = header.factSamplesCount) + num_samples = fact_samples; + + const auto outIndexInput = out.size(); + + if (!(flags & PCMS16_CONVERSION_FLAG_RAW_OUTPUT)) + PCMS16WriteHeader(out, header.fmtChannels, num_samples, header.fmtSampleRate); + + const auto result = ADPCMDecodeData(in, out, header.fmtChannels, num_samples, header.fmtBlockAlign); + + if (!result) + out.resize(outIndexInput); + + return result; +} + +bool PCMS16ToADPCM_ADPCMXQ(const PCMS16_Header &header, const std::span &in, std::vector &out, int flags, int blocksizePow2, int lookahead) +{ + if (!header.dataSize || in.size() < header.dataSize) + return false; + + const auto num_samples = header.dataSize / header.fmtBlockAlign; + + uint16_t block_size; + + if (blocksizePow2 > 0 && blocksizePow2 < 16) + block_size = static_cast(1 << blocksizePow2); + else + block_size = static_cast(0x100 * header.fmtChannels * (header.fmtSampleRate < 11000 ? 1 : header.fmtSampleRate / 11000)); + + const auto samples_per_block = (block_size - header.fmtChannels * 4) * (header.fmtChannels ^ 3) + 1; + + const auto outIndexInput = out.size(); + + if (!(flags & PCMS16_CONVERSION_FLAG_RAW_OUTPUT)) + ADPCMWriteHeader(out, header.fmtChannels, num_samples, header.fmtSampleRate, samples_per_block); + + const auto result = ADPCMEncodeData(in, out, header.fmtChannels, num_samples, samples_per_block, lookahead, + !(flags & PCMS16_CONVERSION_FLAG_ADPCM_DISABLE_NOISE_SHAPING) ? (header.fmtSampleRate > 64000 ? NOISE_SHAPING_STATIC : NOISE_SHAPING_DYNAMIC) : NOISE_SHAPING_OFF); + + if (!result) + out.resize(outIndexInput); + + return result; +} +#endif + +bool PCMS16FromADPCM_LibSNDFile(const ADPCM_Header &header, const std::span &in, std::vector &out, int flags) +{ + if (!header.dataSize || in.size() < header.dataSize) + return false; + + std::vector headerAndIn(sizeof(header) + header.dataSize, '\0'); + std::memcpy(headerAndIn.data(), &header, sizeof(header)); + std::memcpy(headerAndIn.data() + sizeof(header), in.data(), in.size()); + + SF_VIRTUAL_DATA_FIXED virtSndData{const_cast(headerAndIn.data()), static_cast(headerAndIn.size())}; + SndfileHandle sndFile(g_VirtSndFileIOFixed, &virtSndData); + if (sndFile.error() != SF_ERR_NO_ERROR) + { + const auto* err = sndFile.strError(); + return false; + } + + auto frames = static_cast(sndFile.frames()); + if (frames < header.factSamplesCount / header.fmtChannels) + return false; + + frames = header.factSamplesCount / header.fmtChannels; + + // format check already performed, we skip it here + + const auto outIndexInput = out.size(); + if (!(flags & PCMS16_CONVERSION_FLAG_RAW_OUTPUT)) + PCMS16WriteHeader(out, header.fmtChannels, header.factSamplesCount, header.fmtSampleRate); + + //const auto outIndex = out.size(); + out.resize(outIndexInput + header.factSamplesCount); + + size_t outOffset = outIndexInput; + while (frames != 0) + { + static constexpr uint32_t maxFramesPerRead = UINT16_MAX; + const uint32_t framesToRead = std::min(maxFramesPerRead, frames); + if (sndFile.readf(out.data() + outOffset, framesToRead) != framesToRead) + { + sf_close(sndFile.takeOwnership()); + + out.resize(outIndexInput); + return false; + } + + frames -= framesToRead; + outOffset += framesToRead * header.fmtChannels; + } + + return true; +} + +bool PCMS16ToADPCM_LibSNDFile(const PCMS16_Header &header, const std::span &in, std::vector &out, int flags) +{ + if (!header.dataSize || in.size() < header.dataSize) + return false; + + const auto outIndexInput = out.size(); + + SF_VIRTUAL_DATA virtSndData{out}; + SndfileHandle sndFile(g_VirtSndFileIO, &virtSndData, SFM_WRITE, SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, header.fmtChannels, header.fmtSampleRate); + if (sndFile.error() != SF_ERR_NO_ERROR) + { + const auto* err = sndFile.strError(); + out.resize(outIndexInput); + return false; + } + + size_t inOffset = 0; + auto frames = header.dataSize / header.fmtBlockAlign; + while (frames != 0) + { + static constexpr uint32_t maxFramesPerWrite = UINT16_MAX; + const uint32_t framesToWrite = std::min(maxFramesPerWrite, frames); + if (sndFile.writef(in.data() + inOffset, framesToWrite) != framesToWrite) + { + sf_close(sndFile.takeOwnership()); + + out.resize(outIndexInput); + return false; + } + + frames -= framesToWrite; + inOffset += framesToWrite * header.fmtChannels; + } + + if (flags & PCMS16_CONVERSION_FLAG_RAW_OUTPUT) + { + const auto adpcmHeader = ADPCMHeader(out); + std::memmove(out.data(), ADPCMDataView(adpcmHeader, out).data(), adpcmHeader.dataSize); + out.resize(adpcmHeader.dataSize); + } + + return true; +} + +int32_t PCMS16ChangeSampleRate(PCMS16_Header &header, const std::span &data, uint32_t newSampleRate) +{ + assert(header.fmtSampleRate != newSampleRate); + //if (header.fmtSampleRate == newSampleRate) + // return 0; + + SRC_DATA convData; + convData.src_ratio = static_cast(newSampleRate) / header.fmtSampleRate; + + const auto inDataSize = header.dataSize / sizeof(int16_t); + if (data.size() < static_cast(convData.src_ratio * inDataSize)) + return -1; + + // UINT16_MAX is just an extra buffer space in case calculation is wrong, but src_ratio * in_size should be + // enough + std::vector convDataCache(inDataSize + data.size()); + src_short_to_float_array(data.data(), convDataCache.data(), static_cast(inDataSize)); + + convData.data_in = convDataCache.data(); + convData.input_frames = static_cast(inDataSize / header.fmtChannels); + convData.data_out = convDataCache.data() + inDataSize; + convData.output_frames = static_cast(data.size() / header.fmtChannels); + + const auto retVal = src_simple(&convData, SRC_SINC_BEST_QUALITY, header.fmtChannels); + if (retVal != 0 || convData.input_frames != convData.input_frames_used) + return -1; + + header.fmtSampleRate = newSampleRate; + header.fmtAvgBytesRate = newSampleRate * header.fmtBlockAlign; + header.dataSize = convData.output_frames_gen * header.fmtBlockAlign; + header.riffSize = header.dataSize + 0x24; + + src_float_to_short_array(convData.data_out, data.data(), static_cast(data.size())); + + return 1; +} + +int32_t PCMS16ChangeChannelCount(PCMS16_Header &header, const std::span &data, uint16_t newChannelCount) +{ + assert(header.fmtChannels != newChannelCount); + //if (header.fmtChannels == newChannelCount) + // return 0; + + if (header.fmtChannels < newChannelCount) + { + assert(header.fmtChannels == 1); + assert(newChannelCount == 2); + + for (auto i = static_cast(header.dataSize / 2) - 1; i >= 0; --i) + { + data[i * 2] = data[i]; + data[i * 2 + 1] = data[i]; + } + + header.fmtChannels *= 2; + header.fmtAvgBytesRate *= 2; + header.fmtBlockAlign *= 2; + header.dataSize *= 2; + header.riffSize = header.dataSize + 0x24; + + return 1; + } + + assert(header.fmtChannels == 2); + assert(newChannelCount == 1); + + for (size_t i = 0; i < (header.dataSize / 2); ++i) + { + data[i] = static_cast((static_cast(data[i * 2]) + + static_cast(data[i * 2 + 1])) / 2); + } + + header.fmtChannels /= 2; + header.fmtAvgBytesRate /= 2; + header.fmtBlockAlign /= 2; + header.dataSize /= 2; + header.riffSize = header.dataSize + 0x24; + + return 1; +} + +} + +PCMS16_Header PCMS16Header(const SoundRecord &record) +{ + if (record.formatTag == 0x01) + { + PCMS16_Header header; + + header.riffSize += record.dataSize; + header.fmtChannels = record.channels; + header.fmtSampleRate = record.sampleRate; + header.fmtAvgBytesRate = record.sampleRate * record.blockAlign; + header.fmtBlockAlign = record.blockAlign; + header.fmtBitsPerSample = record.bitsPerSample; + header.dataSize = record.dataSize; + + return header; + } + + PCMS16_Header header; + + header.riffSize += record.dataSizeUncompressed; + header.fmtChannels = record.channels; + header.fmtSampleRate = record.sampleRate; + header.fmtBlockAlign = record.channels * sizeof(int16_t); + header.fmtAvgBytesRate = record.sampleRate * header.fmtBlockAlign; + header.fmtBitsPerSample = 16; + header.dataSize = record.dataSizeUncompressed; + + return header; +} + +PCMS16_Header PCMS16Header(const std::span &in) +{ + if (in.size() < sizeof(PCMS16_Header)) + return {}; + + PCMS16_Header header; + std::memcpy(&header, in.data(), sizeof(PCMS16_Header)); + + if (std::memcmp(header.riffId, "RIFF", 4) != 0) + return {}; + + if (std::memcmp(header.waveId, "WAVE", 4) != 0) + return {}; + + if (std::memcmp(header.fmtId, "fmt ", 4) != 0) + return {}; + + if (header.fmtSize != 0x10) + return {}; + + if (header.fmtFormat != 0x01) + return {}; + + if (header.fmtChannels > 2) + return {}; + + if (header.fmtBitsPerSample != 16) + return {}; + + if (std::memcmp(header.dataId, "data", 4) != 0) + return {}; + + if (header.dataSize % header.fmtBlockAlign) + return {}; + + if (!header.dataSize || in.size() < sizeof(PCMS16_Header) + header.dataSize) + return {}; + + return header; +} + +SoundRecord PCMS16SoundRecord(const PCMS16_Header &header, const uint64_t xxh3Hash) +{ + return { + xxh3Hash, + header.dataSize, + header.dataSize, + header.fmtSampleRate, + header.fmtFormat, + header.fmtBitsPerSample, + header.fmtChannels, + header.fmtBlockAlign, + header.fmtChannels + }; +} + +SoundRecord PCMS16SoundRecord(const PCMS16_Header &header, const std::span &in) +{ + if (!header.dataSize || in.size() < header.dataSize) + return {}; + + const auto dataXXH3Hash = XXH3_64bits(in.data(), header.dataSize); + return PCMS16SoundRecord(header, dataXXH3Hash); +} + +SoundRecord PCMS16SoundRecord(const std::span &in) +{ + const auto header = PCMS16Header(in); + return PCMS16SoundRecord(header, PCMS16DataView(header, in)); +} + +std::span PCMS16DataView(const PCMS16_Header &header, const std::span &in) +{ + if (!header.dataSize || in.size() < sizeof(PCMS16_Header) + header.dataSize) + return {}; + + return in.subspan(sizeof(PCMS16_Header) / sizeof(int16_t), header.dataSize); +} + +std::span PCMS16DataView(const std::span &in) +{ + return PCMS16DataView(PCMS16Header(in), in); +} + +ADPCM_Header ADPCMHeader(const SoundRecord &in, int blocksizePow2) +{ + const auto samplesCount = static_cast(in.dataSizeUncompressed / (in.channels * sizeof(int16_t))); + + if (in.formatTag == 0x11) + { + ADPCM_Header header; + + header.riffSize += in.dataSize; + header.fmtChannels = in.channels; + header.fmtSampleRate = in.sampleRate; + header.fmtAvgBytesRate = (in.sampleRate * in.blockAlign) / in.samplesPerBlock; + header.fmtBlockAlign = in.blockAlign; + header.fmtBitsPerSample = in.bitsPerSample; + header.fmtExtraSamplesPerBlock = in.samplesPerBlock; + header.factSamplesCount = samplesCount; + header.dataSize = in.dataSize; + + return header; + } + + uint16_t block_size; + + if (blocksizePow2 > 0 && blocksizePow2 < 16) + block_size = static_cast(1 << blocksizePow2); + else + block_size = static_cast(0x100 * in.channels * (in.sampleRate < 11000 ? 1 : in.sampleRate / 11000)); + + const auto samples_per_block = static_cast((block_size - in.channels * 4) * (in.channels ^ 3) + 1); + + const auto num_blocks = samplesCount / samples_per_block; + const auto leftover_samples = samplesCount % samples_per_block; + const auto total_data_bytes = (num_blocks + (leftover_samples != 0)) * block_size; + + ADPCM_Header header; + header.riffSize += total_data_bytes; + header.fmtChannels = in.channels; + header.fmtSampleRate = in.sampleRate; + header.fmtAvgBytesRate = in.sampleRate * block_size / samples_per_block; + header.fmtBlockAlign = block_size; + header.fmtBitsPerSample = 4; + header.fmtExtraSamplesPerBlock = samples_per_block; + header.factSamplesCount = samplesCount; + header.dataSize = total_data_bytes; + + return header; +} + +ADPCM_Header ADPCMHeader(const std::span &in) +{ + if (in.size() < sizeof(ADPCM_Header)) + return {}; + + ADPCM_Header header; + std::memcpy(&header, in.data(), sizeof(ADPCM_Header)); + + if (std::memcmp(header.riffId, "RIFF", 4) != 0) + return {}; + + if (std::memcmp(header.waveId, "WAVE", 4) != 0) + return {}; + + if (std::memcmp(header.fmtId, "fmt ", 4) != 0) + return {}; + + if (header.fmtSize != 0x14) + return {}; + + if (header.fmtFormat != 0x11) + return {}; + + if (header.fmtChannels > 2) + return {}; + + if (header.fmtBitsPerSample != 4) + return {}; + + if (header.fmtExtraSize != 0x02) + return {}; + + if (std::memcmp(header.factId, "fact", 4) != 0) + return {}; + + if (header.factSize != 0x04) + return {}; + + if (std::memcmp(header.dataId, "data", 4) != 0) + return {}; + + if (header.dataSize % header.fmtBlockAlign) + return {}; + + if (!header.dataSize || in.size() < sizeof(ADPCM_Header) + header.dataSize) + return {}; + + return header; +} + +SoundRecord ADPCMSoundRecord(const ADPCM_Header &header, const uint64_t xxh3Hash) +{ + return { + xxh3Hash, + static_cast(header.factSamplesCount * header.fmtChannels * sizeof(int16_t)), + header.dataSize, + header.fmtSampleRate, + header.fmtFormat, + header.fmtBitsPerSample, + header.fmtChannels, + header.fmtBlockAlign, + header.fmtExtraSamplesPerBlock + }; +} + +SoundRecord ADPCMSoundRecord(const ADPCM_Header &header, const std::span &in, bool pcms16XXH3Hash) +{ + if (!header.dataSize || in.size() < header.dataSize) + return {}; + + if (!pcms16XXH3Hash) + { + const auto dataXXH3Hash = XXH3_64bits(in.data(), header.dataSize); + return ADPCMSoundRecord(header, dataXXH3Hash); + } + + std::vector pcms16Decoded; + if (!PCMS16FromADPCM(header, in, pcms16Decoded, PCMS16_CONVERSION_FLAG_RAW_OUTPUT)) + return {}; + + const auto dataXXH3Hash = XXH3_64bits(pcms16Decoded.data(), pcms16Decoded.size() * sizeof(int16_t)); + return ADPCMSoundRecord(header, dataXXH3Hash); +} + +SoundRecord ADPCMSoundRecord(const std::span &in) +{ + const auto header = ADPCMHeader(in); + return ADPCMSoundRecord(header, ADPCMDataView(header, in)); +} + +std::span ADPCMDataView(const ADPCM_Header &header, const std::span &in) +{ + if (!header.dataSize || in.size() < sizeof(ADPCM_Header) + header.dataSize) + return {}; + + return in.subspan(sizeof(ADPCM_Header), header.dataSize); +} + +std::span ADPCMDataView(const std::span &in) +{ + return ADPCMDataView(ADPCMHeader(in), in); +} + +SoundRecord VorbisHeader(const std::span &in) +{ + if (in.size() < sizeof(uint32_t)) + return {}; + + uint32_t vorbisHeader; + std::memcpy(&vorbisHeader, in.data(), sizeof(uint32_t)); + + if (std::memcmp(&vorbisHeader, "OggS", 4) != 0) + return {}; + + SF_VIRTUAL_DATA_FIXED virtSndData{const_cast(in.data()), static_cast(in.size())}; + SndfileHandle sndFile(g_VirtSndFileIOFixed, &virtSndData); + if (sndFile.error() != SF_ERR_NO_ERROR) + { + const auto* err = sndFile.strError(); + return {}; + } + + const auto format = sndFile.format(); + if ((format & (SF_FORMAT_OGG | SF_FORMAT_VORBIS)) != (SF_FORMAT_OGG | SF_FORMAT_VORBIS)) + return {}; + + const auto frames = static_cast(sndFile.frames()); + if (frames == 0) + return {}; + + const auto channels = static_cast(sndFile.channels()); + if (channels == 0 || channels > 2) + return {}; + + const auto sampleRate = static_cast(sndFile.samplerate()); + if (sampleRate == 0) + return {}; + + return { + 0, + static_cast(frames * channels * sizeof(int16_t)), + static_cast(in.size()), + sampleRate, + 0x1000, + 16, + channels, + static_cast(channels * sizeof(int16_t)), + channels + }; +} + +SoundRecord VorbisSoundRecord(const SoundRecord &header, const uint64_t xxh3Hash) +{ + return { + xxh3Hash, + header.dataSizeUncompressed, + header.dataSize, + header.sampleRate, + header.formatTag, + header.bitsPerSample, + header.channels, + header.blockAlign, + header.samplesPerBlock + }; +} + +SoundRecord VorbisSoundRecord(const SoundRecord &header, const std::span &in, bool pcms16XXH3Hash) +{ + if (!header.dataSize || in.size() < header.dataSize) + return {}; + + if (!pcms16XXH3Hash) + { + const auto dataXXH3Hash = XXH3_64bits(in.data(), header.dataSize); + return VorbisSoundRecord(header, dataXXH3Hash); + } + + std::vector pcms16Decoded; + if (!PCMS16FromVorbis(header, in, pcms16Decoded, PCMS16_CONVERSION_FLAG_RAW_OUTPUT)) + return {}; + + const auto dataXXH3Hash = XXH3_64bits(pcms16Decoded.data(), pcms16Decoded.size() * sizeof(int16_t)); + return VorbisSoundRecord(header, dataXXH3Hash); +} + +SoundRecord VorbisSoundRecord(const std::span &in) +{ + const auto header = VorbisHeader(in); + return VorbisSoundRecord(header, VorbisDataView(header, in)); +} + +std::span VorbisDataView(const SoundRecord &header, const std::span &in) +{ + if (!header.dataSize || in.size() < header.dataSize) + return {}; + + return in.subspan(0, header.dataSize); +} + +std::span VorbisDataView(const std::span &in) +{ + return VorbisDataView(VorbisHeader(in), in); +} + +SoundRecord UnknownSoundDataHeader(const std::span &in) +{ + SF_VIRTUAL_DATA_FIXED virtSndData{const_cast(in.data()), static_cast(in.size())}; + SndfileHandle sndFile(g_VirtSndFileIOFixed, &virtSndData); + if (sndFile.error() != SF_ERR_NO_ERROR) + { + const auto* err = sndFile.strError(); + return {}; + } + + const auto frames = static_cast(sndFile.frames()); + if (frames == 0) + return {}; + + const auto channels = static_cast(sndFile.channels()); + if (channels == 0 || channels > 2) + return {}; + + const auto sampleRate = static_cast(sndFile.samplerate()); + if (sampleRate == 0) + return {}; + + return { + 0, + static_cast(frames * channels * sizeof(int16_t)), + static_cast(in.size()), + sampleRate, + 0x8000, + 16, + channels, + static_cast(channels * sizeof(int16_t)), + channels + }; +} + +SoundRecord UnknownSoundDataSoundRecord(const SoundRecord &header, const uint64_t xxh3Hash) +{ + return { + xxh3Hash, + header.dataSizeUncompressed, + header.dataSize, + header.sampleRate, + header.formatTag, + header.bitsPerSample, + header.channels, + header.blockAlign, + header.samplesPerBlock + }; +} + +SoundRecord UnknownSoundDataSoundRecord(const SoundRecord &header, const std::span &in, bool pcms16XXH3Hash) +{ + if (!header.dataSize || in.size() < header.dataSize) + return {}; + + if (!pcms16XXH3Hash) + { + const auto dataXXH3Hash = XXH3_64bits(in.data(), header.dataSize); + return UnknownSoundDataSoundRecord(header, dataXXH3Hash); + } + + std::vector pcms16Decoded; + if (!PCMS16FromUnknownSoundData(header, in, pcms16Decoded, PCMS16_CONVERSION_FLAG_RAW_OUTPUT)) + return {}; + + const auto dataXXH3Hash = XXH3_64bits(pcms16Decoded.data(), pcms16Decoded.size() * sizeof(int16_t)); + return UnknownSoundDataSoundRecord(header, dataXXH3Hash); +} + +SoundRecord UnknownSoundDataSoundRecord(const std::span &in) +{ + const auto header = UnknownSoundDataHeader(in); + return UnknownSoundDataSoundRecord(header, UnknownSoundDataDataView(header, in)); +} + +std::span UnknownSoundDataDataView(const SoundRecord &header, const std::span &in) +{ + if (!header.dataSize || in.size() < header.dataSize) + return {}; + + return in.subspan(0, header.dataSize); +} + +std::span UnknownSoundDataDataView(const std::span &in) +{ + return UnknownSoundDataDataView(UnknownSoundDataHeader(in), in); +} + +SoundRecord SoundDataHeader(const std::span &in) +{ + const auto pcms16Header = PCMS16Header(ToSpan(in)); + if (pcms16Header.dataSize) + return PCMS16SoundRecord(pcms16Header); + + const auto adpcmHeader = ADPCMHeader(in); + if (adpcmHeader.dataSize) + return ADPCMSoundRecord(adpcmHeader); + + const auto vorbisHeader = VorbisHeader(in); + if (vorbisHeader.dataSize) + return vorbisHeader; + + return UnknownSoundDataHeader(in); +} + +SoundRecord SoundDataSoundRecord(const SoundRecord &header, const uint64_t xxh3Hash) +{ + return { + xxh3Hash, + header.dataSizeUncompressed, + header.dataSize, + header.sampleRate, + header.formatTag, + header.bitsPerSample, + header.channels, + header.blockAlign, + header.samplesPerBlock + }; +} + +SoundRecord SoundDataSoundRecord(const SoundRecord &header, const std::span &in, bool pcms16XXH3Hash) +{ + if (!header.dataSize || in.size() < header.dataSize) + return {}; + + if (!pcms16XXH3Hash || header.formatTag == 0x01) + { + const auto dataXXH3Hash = XXH3_64bits(in.data(), header.dataSize); + return SoundDataSoundRecord(header, dataXXH3Hash); + } + + std::vector pcms16Decoded; + if (!PCMS16FromSoundData(header, in, pcms16Decoded, PCMS16_CONVERSION_FLAG_RAW_OUTPUT)) + return {}; + + const auto dataXXH3Hash = XXH3_64bits(pcms16Decoded.data(), pcms16Decoded.size() * sizeof(int16_t)); + return SoundDataSoundRecord(header, dataXXH3Hash); +} + +SoundRecord SoundDataSoundRecord(const std::span &in) +{ + const auto header = SoundDataHeader(in); + return SoundDataSoundRecord(header, SoundDataDataView(header, in)); +} + +std::span SoundDataDataView(const SoundRecord &header, const std::span &in) +{ + if (!header.dataSize || in.size() < header.dataSize) + return {}; + + switch (header.formatTag) + { + case 0x01: { + return ToSpan(PCMS16DataView(PCMS16Header(header), ToSpan(in))); + } + case 0x11: { + return ADPCMDataView(ADPCMHeader(header), in); + } + case 0x1000: { + return VorbisDataView(header, in); + } + case 0x8000: { + return UnknownSoundDataDataView(header, in); + } + default: { + return {}; + } + } +} + +std::span SoundDataDataView(const std::span &in) +{ + return SoundDataDataView(SoundDataHeader(in), in); +} + +int32_t PCMS16ChangeSampleRate(PCMS16_Header &header, std::vector &data, uint32_t newSampleRate) +{ + if (header.fmtSampleRate == newSampleRate) + return 0; + + const auto outputDataInputIndex = data.size(); + const auto conversionRatio = static_cast(newSampleRate) / header.fmtSampleRate; + + data.resize(std::max(data.size(), static_cast(conversionRatio * data.size()) + UINT16_MAX * sizeof(int16_t))); + + const auto result = PCMS16ChangeSampleRate(header, ToSpan(std::span{data}), newSampleRate); + + data.resize(header.dataSize); + + return result; +} + +int32_t PCMS16ChangeSampleRate(PCMS16_Header &header, std::vector &data, uint32_t newSampleRate) +{ + if (header.fmtSampleRate == newSampleRate) + return 0; + + const auto outputDataInputIndex = data.size(); + const auto conversionRatio = static_cast(newSampleRate) / header.fmtSampleRate; + + data.resize(std::max(data.size(), static_cast(conversionRatio * data.size()) + UINT16_MAX)); + + const auto result = PCMS16ChangeSampleRate(header, std::span{data}, newSampleRate); + + data.resize(header.dataSize / sizeof(int16_t)); + + return result; +} + +int32_t PCMS16ChangeChannelCount(PCMS16_Header &header, std::vector &data, uint16_t newChannelCount) +{ + if (header.fmtChannels == newChannelCount) + return 0; + + if (newChannelCount > header.fmtChannels) + data.resize(data.size() * 2); + + const auto result = PCMS16ChangeChannelCount(header, ToSpan(std::span{data}), newChannelCount); + + data.resize(header.dataSize); + + return result; +} + +int32_t PCMS16ChangeChannelCount(PCMS16_Header &header, std::vector &data, uint16_t newChannelCount) +{ + if (header.fmtChannels == newChannelCount) + return 0; + + if (newChannelCount > header.fmtChannels) + data.resize(data.size() * 2); + + const auto result = PCMS16ChangeChannelCount(header, std::span{data}, newChannelCount); + + data.resize(header.dataSize / sizeof(int16_t)); + + return result; +} + +bool PCMS16FromADPCM(const ADPCM_Header &header, const std::span &in, std::vector &out, int flags) +{ +#if FBL_PCMS16_USE_ADPCMXQ + if (PCMS16FromADPCM_ADPCMXQ(header, in, out, flags)) + return true; +#endif + + return PCMS16FromADPCM_LibSNDFile(header, in, out, flags); +} + +bool PCMS16FromADPCM(const std::span& in, std::vector &out, int flags) +{ + const auto header = ADPCMHeader(in); + return PCMS16FromADPCM(header, ADPCMDataView(in), out, flags); +} + +bool PCMS16FromVorbis(const SoundRecord &header, const std::span &in, std::vector &out, int flags) +{ + if (!header.dataSize || in.size() < header.dataSize) + return false; + + SF_VIRTUAL_DATA_FIXED virtSndData{const_cast(in.data()), static_cast(in.size())}; + SndfileHandle sndFile(g_VirtSndFileIOFixed, &virtSndData); + if (sndFile.error() != SF_ERR_NO_ERROR) + { + const auto* err = sndFile.strError(); + return false; + } + + assert(header.sampleRate == sndFile.samplerate()); + assert(header.channels == sndFile.channels()); + + auto frames = static_cast(sndFile.frames()); + if (frames != header.dataSizeUncompressed / header.blockAlign) + return false; + + // format check already performed, we skip it here + + const auto outIndexInput = out.size(); + if (!(flags & PCMS16_CONVERSION_FLAG_RAW_OUTPUT)) + PCMS16WriteHeader(out, header.channels, header.sampleRate, header.sampleRate); + + const auto outIndex = out.size(); + out.resize(outIndex + header.dataSizeUncompressed / sizeof(int16_t)); + + size_t outOffset = outIndex; + while (frames != 0) + { + static constexpr uint32_t maxFramesPerRead = UINT16_MAX; + const uint32_t framesToRead = std::min(maxFramesPerRead, frames); + if (sndFile.readf(out.data() + outOffset, framesToRead) != framesToRead) + { + sf_close(sndFile.takeOwnership()); + + out.resize(outIndexInput); + return false; + } + + frames -= framesToRead; + outOffset += framesToRead * header.channels; + } + + return true; +} + +bool PCMS16FromVorbis(const std::span &in, std::vector &out, int flags) +{ + const auto header = VorbisHeader(in); + return PCMS16FromVorbis(header, VorbisDataView(in), out, flags); +} + +bool PCMS16FromUnknownSoundData(const SoundRecord &header, const std::span &in, std::vector &out, int flags) +{ + if (!header.dataSize || in.size() < header.dataSize) + return false; + + SF_VIRTUAL_DATA_FIXED virtSndData{const_cast(in.data()), static_cast(in.size())}; + SndfileHandle sndFile(g_VirtSndFileIOFixed, &virtSndData); + if (sndFile.error() != SF_ERR_NO_ERROR) + { + const auto* err = sndFile.strError(); + return false; + } + + assert(header.sampleRate == sndFile.samplerate()); + assert(header.channels == sndFile.channels()); + + auto frames = static_cast(sndFile.frames()); + if (frames != header.dataSizeUncompressed / header.blockAlign) + return false; + + // format check already performed, we skip it here + + const auto outIndexInput = out.size(); + if (!(flags & PCMS16_CONVERSION_FLAG_RAW_OUTPUT)) + PCMS16WriteHeader(out, header.channels, header.sampleRate, header.sampleRate); + + const auto outIndex = out.size(); + out.resize(outIndex + header.dataSizeUncompressed / sizeof(int16_t)); + + size_t outOffset = outIndex; + while (frames != 0) + { + static constexpr uint32_t maxFramesPerRead = UINT16_MAX; + const uint32_t framesToRead = std::min(maxFramesPerRead, frames); + if (sndFile.readf(out.data() + outOffset, framesToRead) != framesToRead) + { + sf_close(sndFile.takeOwnership()); + + out.resize(outIndexInput); + return false; + } + + frames -= framesToRead; + outOffset += framesToRead * header.channels; + } + + return true; +} + +bool PCMS16FromUnknownSoundData(const std::span &in, std::vector &out, int flags) +{ + const auto header = UnknownSoundDataSoundRecord(in); + return PCMS16FromUnknownSoundData(header, UnknownSoundDataDataView(in), out, flags); +} + +bool PCMS16FromSoundData(const SoundRecord &header, const std::span &in, std::vector &out, int flags) +{ + if (!header.dataSize || in.size() < header.dataSize) + return false; + + switch (header.formatTag) + { + case 0x01: { + if (!(flags & PCMS16_CONVERSION_FLAG_RAW_OUTPUT)) + { + const auto pcms16Header = PCMS16Header(header); + + const auto outIndexInput = out.size(); + out.resize(outIndexInput + sizeof(PCMS16_Header) / sizeof(int16_t)); + std::memcpy(out.data() + outIndexInput, &pcms16Header, sizeof(PCMS16_Header)); + } + + const auto outIndexInput = out.size(); + out.resize(outIndexInput + header.dataSize / sizeof(int16_t)); + std::memcpy(out.data() + outIndexInput, in.data(), header.dataSize); + + return true; + } + case 0x11: { + return PCMS16FromADPCM(ADPCMHeader(header), in, out, flags); + } + case 0x1000: { + return PCMS16FromVorbis(header, in, out, flags); + } + case 0x8000: { + return PCMS16FromUnknownSoundData(header, in, out, flags); + } + default: { + return false; + } + } +} + +bool PCMS16FromSoundData(const std::span &in, std::vector &out, int flags) +{ + const auto header = SoundDataSoundRecord(in); + return PCMS16FromSoundData(header, SoundDataDataView(in), out, flags); +} + +bool PCMS16ToADPCM(const PCMS16_Header &header, const std::span &in, std::vector &out, int flags, [[maybe_unused]] int blocksizePow2, [[maybe_unused]] int lookahead) +{ +#if FBL_PCMS16_USE_ADPCMXQ + if (PCMS16ToADPCM_ADPCMXQ(header, in, out, flags, blocksizePow2, lookahead)) + return true; +#endif + + return PCMS16ToADPCM_LibSNDFile(header, in, out, flags); +} + +bool PCMS16ToADPCM(const std::span& in, std::vector &out, int flags, int blocksizePow2, int lookahead) +{ + const auto header = PCMS16Header(in); + return PCMS16ToADPCM(header, PCMS16DataView(header, in), out, flags, blocksizePow2, lookahead); +} + +bool PCMS16ToVorbis(const PCMS16_Header &header, const std::span &in, std::vector &out, int) +{ + if (!header.dataSize || in.size() < header.dataSize) + return false; + + const auto outIndexInput = out.size(); + + SF_VIRTUAL_DATA virtSndData{out}; + SndfileHandle sndFile(g_VirtSndFileIO, &virtSndData, SFM_WRITE, SF_FORMAT_OGG | SF_FORMAT_VORBIS, header.fmtChannels, header.fmtSampleRate); + if (sndFile.error() != SF_ERR_NO_ERROR) + { + const auto* err = sndFile.strError(); + out.resize(outIndexInput); + return false; + } + + assert(header.fmtSampleRate == sndFile.samplerate()); + assert(header.fmtChannels == sndFile.channels()); + + size_t inOffset = 0; + auto frames = header.dataSize / header.fmtBlockAlign; + while (frames != 0) + { + static constexpr uint32_t maxFramesPerWrite = UINT16_MAX; + const uint32_t framesToWrite = std::min(maxFramesPerWrite, frames); + if (sndFile.writef(in.data() + inOffset, framesToWrite) != framesToWrite) + { + sf_close(sndFile.takeOwnership()); + + out.resize(outIndexInput); + return false; + } + + frames -= framesToWrite; + inOffset += framesToWrite * header.fmtChannels; + } + + return true; +} + +bool PCMS16ToVorbis(const std::span &in, std::vector &out, int flags) +{ + const auto header = PCMS16Header(in); + return PCMS16ToVorbis(header, PCMS16DataView(header, in), out, flags); +} diff --git a/vendor/FeldarianBaseLibrary/vendor/adpcm-xq/README b/vendor/FeldarianBaseLibrary/vendor/adpcm-xq/README new file mode 100644 index 0000000..6c9ab2a --- /dev/null +++ b/vendor/FeldarianBaseLibrary/vendor/adpcm-xq/README @@ -0,0 +1,59 @@ +//////////////////////////////////////////////////////////////////////////// +// **** ADPCM-XQ **** // +// Xtreme Quality ADPCM Encoder/Decoder // +// Copyright (c) 2022 David Bryant. // +// All Rights Reserved. // +// Distributed under the BSD Software License (see license.txt) // +//////////////////////////////////////////////////////////////////////////// + +While very popular at the end of the last century, ADPCM is no longer a +common audio encoding format, and is certainly not recommended as a general +purpose encoder. However, it requires minimal CPU resources for decoding, +and so still is ideally suited for certain embedded games and applications +that contain canned audio samples. + +This encoder combines two different techniques to achieve higher quality +than existing ADPCM encoders while remaining fully compatible with standard +decoders. The first is dynamic noise shaping, which shifts the quantization +noise up or down in frequency based on the spectrum of the source signal. +This technique is identical to the algorithm used in WavPack's lossy mode +and can make any audible quantization noise much less annoying (or, in some +cases, inaudible). + +The other technique is "lookahead" in which the encoder exhaustively +searches ahead to find the optimum coding sequence based on future samples. +This process can reduce the quantization noise from about 1 to 6 dB (depending +on the source) and also reduces or eliminates the harmonic content in the +noise that sometimes plagues ADPCM. Unfortunately, at its maximum settings +this can be very slow, but this should be relatively irrelevant if the +encoder is being used to generate canned samples. + +Adpcm-xq consists of two standard C files and builds with a single command +on most platforms. It has been designed with maximum portability in mind +and should work correctly even on 16-bit and big-endian architectures +(WAV files are of course always little-endian). + +Linux: +% gcc -O2 *.c -o adpcm-xq + +Darwin/Mac: +% clang -O2 *.c -o adpcm-xq + +MS Visual Studio: +cl -O2 adpcm-xq.c adpcm-lib.c + +Bugs: + +1. Unknown RIFF chunk types are correctly parsed on input files, but are not + passed to the output file. + +2. The lookahead feature does not work for the last samples in an ADPCM + block (i.e. it doesn't utilize samples in the _next_ block). + +3. In some situations the lookahead can get very slow or seem to be stuck + because it needs improved trellis pruning. However the default level 3 + should always be fine and then the user can simply try increasing levels + until the time becomes untenable. + +4. Pipes are not yet supported. + diff --git a/vendor/FeldarianBaseLibrary/vendor/adpcm-xq/adpcm-lib.c b/vendor/FeldarianBaseLibrary/vendor/adpcm-xq/adpcm-lib.c new file mode 100644 index 0000000..9190985 --- /dev/null +++ b/vendor/FeldarianBaseLibrary/vendor/adpcm-xq/adpcm-lib.c @@ -0,0 +1,415 @@ +//////////////////////////////////////////////////////////////////////////// +// **** ADPCM-XQ **** // +// Xtreme Quality ADPCM Encoder/Decoder // +// Copyright (c) 2022 David Bryant. // +// All Rights Reserved. // +// Distributed under the BSD Software License (see license.txt) // +//////////////////////////////////////////////////////////////////////////// + +#include "adpcm-lib.h" + +#include +#include + +/* This module encodes and decodes 4-bit ADPCM (DVI/IMA varient). ADPCM data is divided + * into independently decodable blocks that can be relatively small. The most common + * configuration is to store 505 samples into a 256 byte block, although other sizes are + * permitted as long as the number of samples is one greater than a multiple of 8. When + * multiple channels are present, they are interleaved in the data with an 8-sample + * interval. + */ + +/********************************* 4-bit ADPCM encoder ********************************/ + +#define CLIP(data, min, max) \ +if ((data) > (max)) data = max; \ +else if ((data) < (min)) data = min; + +/* step table */ +static const uint16_t step_table[89] = { + 7, 8, 9, 10, 11, 12, 13, 14, + 16, 17, 19, 21, 23, 25, 28, 31, + 34, 37, 41, 45, 50, 55, 60, 66, + 73, 80, 88, 97, 107, 118, 130, 143, + 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, + 724, 796, 876, 963, 1060, 1166, 1282, 1411, + 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, + 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, + 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, + 32767 +}; + +/* step index tables */ +static const int index_table[] = { + /* adpcm data size is 4 */ + -1, -1, -1, -1, 2, 4, 6, 8 +}; + +struct adpcm_channel { + int32_t pcmdata; // current PCM value + int32_t error, weight, history [2]; // for noise shaping + int8_t index; // current index into step size table +}; + +struct adpcm_context { + struct adpcm_channel channels [2]; + int num_channels, lookahead, noise_shaping; +}; + +/* Create ADPCM encoder context with given number of channels. + * The returned pointer is used for subsequent calls. Note that + * even though an ADPCM encoder could be set up to encode frames + * independently, we use a context so that we can use previous + * data to improve quality (this encoder might not be optimal + * for encoding independent frames). + */ + +void *adpcm_create_context (int num_channels, int lookahead, int noise_shaping, int32_t initial_deltas [2]) +{ + struct adpcm_context *pcnxt = malloc (sizeof (struct adpcm_context)); + int ch, i; + + memset (pcnxt, 0, sizeof (struct adpcm_context)); + pcnxt->noise_shaping = noise_shaping; + pcnxt->num_channels = num_channels; + pcnxt->lookahead = lookahead; + + // given the supplied initial deltas, search for and store the closest index + + for (ch = 0; ch < num_channels; ++ch) + for (i = 0; i <= 88; i++) + if (i == 88 || initial_deltas [ch] < ((int32_t) step_table [i] + step_table [i+1]) / 2) { + pcnxt->channels [ch].index = i; + break; + } + + return pcnxt; +} + +/* Free the ADPCM encoder context. + */ + +void adpcm_free_context (void *p) +{ + struct adpcm_context *pcnxt = (struct adpcm_context *) p; + + free (pcnxt); +} + +static void set_decode_parameters (struct adpcm_context *pcnxt, int32_t *init_pcmdata, int8_t *init_index) +{ + int ch; + + for (ch = 0; ch < pcnxt->num_channels; ch++) { + pcnxt->channels[ch].pcmdata = init_pcmdata[ch]; + pcnxt->channels[ch].index = init_index[ch]; + } +} + +static void get_decode_parameters (struct adpcm_context *pcnxt, int32_t *init_pcmdata, int8_t *init_index) +{ + int ch; + + for (ch = 0; ch < pcnxt->num_channels; ch++) { + init_pcmdata[ch] = pcnxt->channels[ch].pcmdata; + init_index[ch] = pcnxt->channels[ch].index; + } +} + +static double minimum_error (const struct adpcm_channel *pchan, int nch, int32_t csample, const int16_t *sample, int depth, int *best_nibble) +{ + int32_t delta = csample - pchan->pcmdata; + struct adpcm_channel chan = *pchan; + uint16_t step = step_table[chan.index]; + uint16_t trial_delta = (step >> 3); + int nibble, nibble2; + double min_error; + + if (delta < 0) { + int mag = (-delta << 2) / step; + nibble = 0x8 | (mag > 7 ? 7 : mag); + } + else { + int mag = (delta << 2) / step; + nibble = mag > 7 ? 7 : mag; + } + + if (nibble & 1) trial_delta += (step >> 2); + if (nibble & 2) trial_delta += (step >> 1); + if (nibble & 4) trial_delta += step; + + if (nibble & 8) + chan.pcmdata -= trial_delta; + else + chan.pcmdata += trial_delta; + + CLIP(chan.pcmdata, -32768, 32767); + if (best_nibble) *best_nibble = nibble; + min_error = (double) (chan.pcmdata - csample) * (chan.pcmdata - csample); + + if (depth) { + chan.index += index_table[nibble & 0x07]; + CLIP(chan.index, 0, 88); + min_error += minimum_error (&chan, nch, sample [nch], sample + nch, depth - 1, NULL); + } + else + return min_error; + + for (nibble2 = 0; nibble2 <= 0xF; ++nibble2) { + double error; + + if (nibble2 == nibble) + continue; + + chan = *pchan; + trial_delta = (step >> 3); + + if (nibble2 & 1) trial_delta += (step >> 2); + if (nibble2 & 2) trial_delta += (step >> 1); + if (nibble2 & 4) trial_delta += step; + + if (nibble2 & 8) + chan.pcmdata -= trial_delta; + else + chan.pcmdata += trial_delta; + + CLIP(chan.pcmdata, -32768, 32767); + + error = (double) (chan.pcmdata - csample) * (chan.pcmdata - csample); + + if (error < min_error) { + chan.index += index_table[nibble2 & 0x07]; + CLIP(chan.index, 0, 88); + error += minimum_error (&chan, nch, sample [nch], sample + nch, depth - 1, NULL); + + if (error < min_error) { + if (best_nibble) *best_nibble = nibble2; + min_error = error; + } + } + } + + return min_error; +} + +static uint8_t encode_sample (struct adpcm_context *pcnxt, int ch, const int16_t *sample, int num_samples) +{ + struct adpcm_channel *pchan = pcnxt->channels + ch; + int32_t csample = *sample; + int depth = num_samples - 1, nibble; + uint16_t step = step_table[pchan->index]; + uint16_t trial_delta = (step >> 3); + + if (pcnxt->noise_shaping == NOISE_SHAPING_DYNAMIC) { + int32_t sam = (3 * pchan->history [0] - pchan->history [1]) >> 1; + int32_t temp = csample - (((pchan->weight * sam) + 512) >> 10); + int32_t shaping_weight; + + if (sam && temp) pchan->weight -= (((sam ^ temp) >> 29) & 4) - 2; + pchan->history [1] = pchan->history [0]; + pchan->history [0] = csample; + + shaping_weight = (pchan->weight < 256) ? 1024 : 1536 - (pchan->weight * 2); + temp = -((shaping_weight * pchan->error + 512) >> 10); + + if (shaping_weight < 0 && temp) { + if (temp == pchan->error) + temp = (temp < 0) ? temp + 1 : temp - 1; + + pchan->error = -csample; + csample += temp; + } + else + pchan->error = -(csample += temp); + } + else if (pcnxt->noise_shaping == NOISE_SHAPING_STATIC) + pchan->error = -(csample -= pchan->error); + + if (depth > pcnxt->lookahead) + depth = pcnxt->lookahead; + + minimum_error (pchan, pcnxt->num_channels, csample, sample, depth, &nibble); + + if (nibble & 1) trial_delta += (step >> 2); + if (nibble & 2) trial_delta += (step >> 1); + if (nibble & 4) trial_delta += step; + + if (nibble & 8) + pchan->pcmdata -= trial_delta; + else + pchan->pcmdata += trial_delta; + + pchan->index += index_table[nibble & 0x07]; + CLIP(pchan->index, 0, 88); + CLIP(pchan->pcmdata, -32768, 32767); + + if (pcnxt->noise_shaping) + pchan->error += pchan->pcmdata; + + return nibble; +} + +static void encode_chunks (struct adpcm_context *pcnxt, uint8_t **outbuf, size_t *outbufsize, const int16_t **inbuf, int inbufcount) +{ + const int16_t *pcmbuf; + int chunks, ch, i; + + chunks = (inbufcount - 1) / 8; + *outbufsize += (chunks * 4) * pcnxt->num_channels; + + while (chunks--) + { + for (ch = 0; ch < pcnxt->num_channels; ch++) + { + pcmbuf = *inbuf + ch; + + for (i = 0; i < 4; i++) { + **outbuf = encode_sample (pcnxt, ch, pcmbuf, chunks * 8 + (3 - i) * 2 + 2); + pcmbuf += pcnxt->num_channels; + **outbuf |= encode_sample (pcnxt, ch, pcmbuf, chunks * 8 + (3 - i) * 2 + 1) << 4; + pcmbuf += pcnxt->num_channels; + (*outbuf)++; + } + } + + *inbuf += 8 * pcnxt->num_channels; + } +} + +/* Encode a block of 16-bit PCM data into 4-bit ADPCM. + * + * Parameters: + * p the context returned by adpcm_begin() + * outbuf destination buffer + * outbufsize pointer to variable where the number of bytes written + * will be stored + * inbuf source PCM samples + * inbufcount number of composite PCM samples provided (note: this is + * the total number of 16-bit samples divided by the number + * of channels) + * + * Returns 1 (for success as there is no error checking) + */ + +int adpcm_encode_block (void *p, uint8_t *outbuf, size_t *outbufsize, const int16_t *inbuf, int inbufcount) +{ + struct adpcm_context *pcnxt = (struct adpcm_context *) p; + int32_t init_pcmdata[2]; + int8_t init_index[2]; + int ch; + + *outbufsize = 0; + + if (!inbufcount) + return 1; + + get_decode_parameters(pcnxt, init_pcmdata, init_index); + + for (ch = 0; ch < pcnxt->num_channels; ch++) { + init_pcmdata[ch] = *inbuf++; + outbuf[0] = init_pcmdata[ch]; + outbuf[1] = init_pcmdata[ch] >> 8; + outbuf[2] = init_index[ch]; + outbuf[3] = 0; + + outbuf += 4; + *outbufsize += 4; + } + + set_decode_parameters(pcnxt, init_pcmdata, init_index); + encode_chunks (pcnxt, &outbuf, outbufsize, &inbuf, inbufcount); + + return 1; +} + +/********************************* 4-bit ADPCM decoder ********************************/ + +/* Decode the block of ADPCM data into PCM. This requires no context because ADPCM blocks + * are indeppendently decodable. This assumes that a single entire block is always decoded; + * it must be called multiple times for multiple blocks and cannot resume in the middle of a + * block. + * + * Parameters: + * outbuf destination for interleaved PCM samples + * inbuf source ADPCM block + * inbufsize size of source ADPCM block + * channels number of channels in block (must be determined from other context) + * + * Returns number of converted composite samples (total samples divided by number of channels) + */ + +int adpcm_decode_block (int16_t *outbuf, const uint8_t *inbuf, size_t inbufsize, int channels) +{ + int ch, samples = 1, chunks; + int32_t pcmdata[2]; + int8_t index[2]; + + if (inbufsize < (uint32_t) channels * 4) + return 0; + + for (ch = 0; ch < channels; ch++) { + *outbuf++ = pcmdata[ch] = (int16_t) (inbuf [0] | (inbuf [1] << 8)); + index[ch] = inbuf [2]; + + if (index [ch] < 0 || index [ch] > 88 || inbuf [3]) // sanitize the input a little... + return 0; + + inbufsize -= 4; + inbuf += 4; + } + + chunks = inbufsize / (channels * 4); + samples += chunks * 8; + + while (chunks--) { + int ch, i; + + for (ch = 0; ch < channels; ++ch) { + + for (i = 0; i < 4; ++i) { + uint16_t step = step_table [index [ch]], delta = step >> 3; + + if (*inbuf & 1) delta += (step >> 2); + if (*inbuf & 2) delta += (step >> 1); + if (*inbuf & 4) delta += step; + + if (*inbuf & 8) + pcmdata[ch] -= delta; + else + pcmdata[ch] += delta; + + index[ch] += index_table [*inbuf & 0x7]; + CLIP(index[ch], 0, 88); + CLIP(pcmdata[ch], -32768, 32767); + outbuf [i * 2 * channels] = pcmdata[ch]; + + step = step_table [index [ch]]; delta = step >> 3; + + if (*inbuf & 0x10) delta += (step >> 2); + if (*inbuf & 0x20) delta += (step >> 1); + if (*inbuf & 0x40) delta += step; + + if (*inbuf & 0x80) + pcmdata[ch] -= delta; + else + pcmdata[ch] += delta; + + index[ch] += index_table [(*inbuf >> 4) & 0x7]; + CLIP(index[ch], 0, 88); + CLIP(pcmdata[ch], -32768, 32767); + outbuf [(i * 2 + 1) * channels] = pcmdata[ch]; + + inbuf++; + } + + outbuf++; + } + + outbuf += channels * 7; + } + + return samples; +} + diff --git a/vendor/FeldarianBaseLibrary/vendor/adpcm-xq/adpcm-lib.h b/vendor/FeldarianBaseLibrary/vendor/adpcm-xq/adpcm-lib.h new file mode 100644 index 0000000..120242e --- /dev/null +++ b/vendor/FeldarianBaseLibrary/vendor/adpcm-xq/adpcm-lib.h @@ -0,0 +1,44 @@ +//////////////////////////////////////////////////////////////////////////// +// **** ADPCM-XQ **** // +// Xtreme Quality ADPCM Encoder/Decoder // +// Copyright (c) 2015 David Bryant. // +// All Rights Reserved. // +// Distributed under the BSD Software License (see license.txt) // +//////////////////////////////////////////////////////////////////////////// + +#ifndef ADPCMLIB_H_ +#define ADPCMLIB_H_ + +#define NOISE_SHAPING_OFF 0 // flat noise (no shaping) +#define NOISE_SHAPING_STATIC 1 // first-order highpass shaping +#define NOISE_SHAPING_DYNAMIC 2 // dynamically tilted noise based on signal + +#if defined(_MSC_VER) && _MSC_VER < 1600 +typedef unsigned __int64 uint64_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int8 uint8_t; +typedef __int64 int64_t; +typedef __int32 int32_t; +typedef __int16 int16_t; +typedef __int8 int8_t; +#else +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +void *adpcm_create_context (int num_channels, int lookahead, int noise_shaping, int32_t initial_deltas [2]); +int adpcm_encode_block (void *p, uint8_t *outbuf, size_t *outbufsize, const int16_t *inbuf, int inbufcount); +int adpcm_decode_block (int16_t *outbuf, const uint8_t *inbuf, size_t inbufsize, int channels); +void adpcm_free_context (void *p); + +#ifdef __cplusplus +} +#endif + + +#endif /* ADPCMLIB_H_ */ diff --git a/vendor/FeldarianBaseLibrary/vendor/adpcm-xq/license.txt b/vendor/FeldarianBaseLibrary/vendor/adpcm-xq/license.txt new file mode 100644 index 0000000..65d4a2e --- /dev/null +++ b/vendor/FeldarianBaseLibrary/vendor/adpcm-xq/license.txt @@ -0,0 +1,25 @@ + Copyright (c) David Bryant + All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Conifer Software 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. diff --git a/vendor/FeldarianBaseLibrary/xmake.lua b/vendor/FeldarianBaseLibrary/xmake.lua new file mode 100644 index 0000000..57e679e --- /dev/null +++ b/vendor/FeldarianBaseLibrary/xmake.lua @@ -0,0 +1,162 @@ +set_xmakever("2.8.1") + +set_allowedplats("windows") +set_arch("x64") + +set_languages("cxx20") + +add_rules("plugin.vsxmake.autoupdate") +add_rules("c.unity_build") +add_rules("c++.unity_build") + +add_defines("UNICODE=1", "_UNICODE=1") + +if (is_plat("windows")) then + add_cxflags("/bigobj", "/utf-8", {tools = {"clang_cl", "cl"}}) + add_cxflags("/MP", {tools = {"cl"}}) + add_defines("_CRT_SECURE_NO_WARNINGS=1", "WIN32_LEAN_AND_MEAN=1", "NOMINMAX=1", "WINVER=_WIN32_WINNT_WIN10", "_WIN32_WINNT=_WIN32_WINNT_WIN10", "NTDDI=NTDDI_WIN10_19H1") +end + +local vsRuntime = "MD" + +if is_mode("debug") then + add_defines("_DEBUG") + set_symbols("debug") + set_optimize("none") + set_warnings("all") + set_policy("build.optimization.lto", false) + + --add_cxflags("/fsanitize=address") + --add_mxflags("/fsanitize=address") + --add_ldflags("/fsanitize=address") + + vsRuntime = vsRuntime.."d" +elseif is_mode("releasedbg") then + add_defines("_DEBUG") + set_symbols("debug") + set_optimize("fastest") + set_warnings("all") + set_policy("build.optimization.lto", true) + + --add_cxflags("/fsanitize=address") + --add_mxflags("/fsanitize=address") + --add_ldflags("/fsanitize=address") + + vsRuntime = vsRuntime.."d" +elseif is_mode("release") then + add_defines("NDEBUG") + set_symbols("hidden") + set_strip("all") + set_optimize("fastest") + set_warnings("all", "error") + set_policy("build.optimization.lto", true) +end + +set_runtimes(vsRuntime); + +add_cxflags("-Wno-microsoft-include", "-Wno-unused-command-line-argument", "-Wno-pragma-system-header-outside-header", {tools = {"clang_cl", "clang"}}) + +add_requireconfs("*", { configs = { debug = is_mode("debug"), lto = not is_mode("debug"), shared = false, vs_runtime = vsRuntime } }) + +add_requires("libsndfile 1.2.0", { configs = { shared = true } }) +add_requires("xxhash v0.8.1") +add_requires("icu4c 73.2", { configs = { shared = true } }) + +add_requires("toml++ 4a28c36c435d813ddbd39a9a48a79d8c862c547f", { configs = { header_only = true } }) -- 3.3.0 with extra patches +add_requires("libsamplerate 22bd06eb114850ebe31981eb794d150a95439fef") -- 0.2.2 with extra patches + +option("fbl-use-pcms16") + set_default(true) + set_showmenu(true) + set_description("Compile PCMS16 module into Feldarian Base Library.") + set_category("Feldarian Base Library/PCMS16") + add_defines("FBL_USE_PCMS16=1", { public = true }) +option_end() + +option("fbl-use-utf") + set_default(true) + set_showmenu(true) + set_description("Compile UTF module into Feldarian Base Library.") + set_category("Feldarian Base Library/UTF") + add_defines("FBL_USE_UTF=1", { public = true }) +option_end() + +option("fbl-pcms16-use-adpcmxq") + add_deps("fbl-use-pcms16") + set_default(true) + set_showmenu(true) + set_description("Use ADPCM-XQ library for IMA ADPCM instead of libsndfile.") + set_category("Feldarian Base Library/PCMS16") + add_defines("FBL_PCMS16_USE_ADPCMXQ=1") +option_end() + +if has_config("fbl-pcms16-use-adpcmxq") then + target("adpcm-xq") + set_version("0.4.0") + set_kind("static") + + set_warnings("none") + + add_includedirs("vendor/adpcm-xq", {public = true}) + + add_headerfiles("vendor/adpcm-xq/**.h") + add_files("vendor/adpcm-xq/**.c") + target_end() +end + +if has_config("fbl-use-pcms16") then + target("FeldarianBaseLibrary_PCMS16") + set_version("0.1.0") + set_kind("static") + + set_options("fbl-use-pcms16", "fbl-pcms16-use-adpcmxq") + + if has_config("fbl-pcms16-use-adpcmxq") then + add_deps("adpcm-xq", {private = true}) + end + + add_defines("ENABLE_SNDFILE_WINDOWS_PROTOTYPES=1") + + add_includedirs("include", {public = false}) + + add_headerfiles("include/Feldarian/PCMS16/**.hpp") + add_files("src/PCMS16/**.cpp") + + add_packages("libsndfile", "libsamplerate", "xxhash") + target_end() +end + +if has_config("fbl-use-utf") then + target("FeldarianBaseLibrary_UTF") + set_version("0.1.0") + set_kind("headeronly") + + set_options("fbl-use-utf") + + add_defines("TOML_EXCEPTIONS=0", { public = true }) + + add_includedirs("include", {public = false}) + + add_headerfiles("include/Feldarian/UTF/**.hpp") + --add_files("src/UTF/**.cpp") + + add_packages("xxhash", "toml++", "icu4c") + target_end() +end + +target("FeldarianBaseLibrary") + set_version("0.1.0") + set_kind("phony") + + set_options("fbl-use-pcms16", "fbl-use-utf") + + add_includedirs("include", {public = true}) + + if has_config("fbl-use-pcms16") then + add_deps("FeldarianBaseLibrary_PCMS16") + end + + if has_config("fbl-use-utf") then + add_deps("FeldarianBaseLibrary_UTF") + end +target_end() diff --git a/vendor/imgui-backends/LICENSE.md b/vendor/imgui-backends/LICENSE.md new file mode 100644 index 0000000..fb715bd --- /dev/null +++ b/vendor/imgui-backends/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2023 Omar Cornut + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/imgui-backends/README.md b/vendor/imgui-backends/README.md new file mode 100644 index 0000000..11d793e --- /dev/null +++ b/vendor/imgui-backends/README.md @@ -0,0 +1,6 @@ +# Dear ImGui SDL2 Backends + +Version 1.89.7-docking. + +Copies of files with same filename from https://github.com/ocornut/imgui/tree/dc3e531ff28450bff73fde0163b1d076b6bb5605/backends with the following changes: +- separated into `include` and `src` directories diff --git a/vendor/imgui-backends/include/imgui/backends/sdl2.h b/vendor/imgui-backends/include/imgui/backends/sdl2.h new file mode 100644 index 0000000..1698ed1 --- /dev/null +++ b/vendor/imgui-backends/include/imgui/backends/sdl2.h @@ -0,0 +1,38 @@ +// dear imgui: Platform Backend for SDL2 +// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) +// (Info: SDL2 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.) + +// Implemented features: +// [X] Platform: Clipboard support. +// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen. +// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] +// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. +// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. +// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. +// Missing features: +// [ ] Platform: Multi-viewport + Minimized windows seems to break mouse wheel events (at least under Windows). +// [x] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +#pragma once + +struct SDL_Window; +struct SDL_Renderer; +typedef union SDL_Event SDL_Event; + +IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context); +IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window); +IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window); +IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window); +IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer); +IMGUI_IMPL_API void ImGui_ImplSDL2_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplSDL2_NewFrame(); +IMGUI_IMPL_API bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event); + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS +static inline void ImGui_ImplSDL2_NewFrame(SDL_Window*) { ImGui_ImplSDL2_NewFrame(); } // 1.84: removed unnecessary parameter +#endif diff --git a/vendor/imgui-backends/include/imgui/backends/sdlrenderer2.h b/vendor/imgui-backends/include/imgui/backends/sdlrenderer2.h new file mode 100644 index 0000000..75aa7f2 --- /dev/null +++ b/vendor/imgui-backends/include/imgui/backends/sdlrenderer2.h @@ -0,0 +1,29 @@ +// dear imgui: Renderer Backend for SDL_Renderer for SDL2 +// (Requires: SDL 2.0.17+) + +// Note how SDL_Renderer is an _optional_ component of SDL2. +// For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX. +// If your application will want to render any non trivial amount of graphics other than UI, +// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user and +// it might be difficult to step out of those boundaries. + +// Implemented features: +// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID! +// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. +// Missing features: +// [ ] Renderer: Multi-viewport support (multiple windows). + +#pragma once + +struct SDL_Renderer; + +IMGUI_IMPL_API bool ImGui_ImplSDLRenderer2_Init(SDL_Renderer* renderer); +IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_NewFrame(); +IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data); + +// Called by Init/NewFrame/Shutdown +IMGUI_IMPL_API bool ImGui_ImplSDLRenderer2_CreateFontsTexture(); +IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_DestroyFontsTexture(); +IMGUI_IMPL_API bool ImGui_ImplSDLRenderer2_CreateDeviceObjects(); +IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_DestroyDeviceObjects(); diff --git a/vendor/imgui-backends/src/sdl2.cpp b/vendor/imgui-backends/src/sdl2.cpp new file mode 100644 index 0000000..ab39806 --- /dev/null +++ b/vendor/imgui-backends/src/sdl2.cpp @@ -0,0 +1,1041 @@ +// dear imgui: Platform Backend for SDL2 +// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) +// (Info: SDL2 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.) +// (Prefer SDL 2.0.5+ for full feature support.) + +// Implemented features: +// [X] Platform: Clipboard support. +// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen. +// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] +// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. +// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. +// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. +// Missing features: +// [ ] Platform: Multi-viewport + Minimized windows seems to break mouse wheel events (at least under Windows). +// [x] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!. + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. +// 2023-04-06: Inputs: Avoid calling SDL_StartTextInput()/SDL_StopTextInput() as they don't only pertain to IME. It's unclear exactly what their relation is to IME. (#6306) +// 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen. (#2702) +// 2023-02-23: Accept SDL_GetPerformanceCounter() not returning a monotonically increasing value. (#6189, #6114, #3644) +// 2023-02-07: Implement IME handler (io.SetPlatformImeDataFn will call SDL_SetTextInputRect()/SDL_StartTextInput()). +// 2023-02-07: *BREAKING CHANGE* Renamed this backend file from imgui_impl_sdl.cpp/.h to imgui_impl_sdl2.cpp/.h in prevision for the future release of SDL3. +// 2023-02-02: Avoid calling SDL_SetCursor() when cursor has not changed, as the function is surprisingly costly on Mac with latest SDL (may be fixed in next SDL version). +// 2023-02-02: Added support for SDL 2.0.18+ preciseX/preciseY mouse wheel data for smooth scrolling + Scaling X value on Emscripten (bug?). (#4019, #6096) +// 2023-02-02: Removed SDL_MOUSEWHEEL value clamping, as values seem correct in latest Emscripten. (#4019) +// 2023-02-01: Flipping SDL_MOUSEWHEEL 'wheel.x' value to match other backends and offer consistent horizontal scrolling direction. (#4019, #6096, #1463) +// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. +// 2022-09-26: Inputs: Disable SDL 2.0.22 new "auto capture" (SDL_HINT_MOUSE_AUTO_CAPTURE) which prevents drag and drop across windows for multi-viewport support + don't capture when drag and dropping. (#5710) +// 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported). +// 2022-03-22: Inputs: Fix mouse position issues when dragging outside of boundaries. SDL_CaptureMouse() erroneously still gives out LEAVE events when hovering OS decorations. +// 2022-03-22: Inputs: Added support for extra mouse buttons (SDL_BUTTON_X1/SDL_BUTTON_X2). +// 2022-02-04: Added SDL_Renderer* parameter to ImGui_ImplSDL2_InitForSDLRenderer(), so we can use SDL_GetRendererOutputSize() instead of SDL_GL_GetDrawableSize() when bound to a SDL_Renderer. +// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago) with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion. +// 2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support, instead of writing directly to io.NavInputs[]. +// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+). +// 2022-01-17: Inputs: always update key mods next and before key event (not in NewFrame) to fix input queue with very low framerates. +// 2022-01-12: Update mouse inputs using SDL_MOUSEMOTION/SDL_WINDOWEVENT_LEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API. +// 2022-01-12: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted. +// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. +// 2021-08-17: Calling io.AddFocusEvent() on SDL_WINDOWEVENT_FOCUS_GAINED/SDL_WINDOWEVENT_FOCUS_LOST. +// 2021-07-29: Inputs: MousePos is correctly reported when the host platform window is hovered but not focused (using SDL_GetMouseFocus() + SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, requires SDL 2.0.5+) +// 2021-06:29: *BREAKING CHANGE* Removed 'SDL_Window* window' parameter to ImGui_ImplSDL2_NewFrame() which was unnecessary. +// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). +// 2021-03-22: Rework global mouse pos availability check listing supported platforms explicitly, effectively fixing mouse access on Raspberry Pi. (#2837, #3950) +// 2020-05-25: Misc: Report a zero display-size when window is minimized, to be consistent with other backends. +// 2020-02-20: Inputs: Fixed mapping for ImGuiKey_KeyPadEnter (using SDL_SCANCODE_KP_ENTER instead of SDL_SCANCODE_RETURN2). +// 2019-12-17: Inputs: On Wayland, use SDL_GetMouseState (because there is no global mouse state). +// 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor. +// 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter. +// 2019-04-23: Inputs: Added support for SDL_GameController (if ImGuiConfigFlags_NavEnableGamepad is set by user application). +// 2019-03-12: Misc: Preserve DisplayFramebufferScale when main window is minimized. +// 2018-12-21: Inputs: Workaround for Android/iOS which don't seem to handle focus related calls. +// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. +// 2018-11-14: Changed the signature of ImGui_ImplSDL2_ProcessEvent() to take a 'const SDL_Event*'. +// 2018-08-01: Inputs: Workaround for Emscripten which doesn't seem to handle focus related calls. +// 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor. +// 2018-06-08: Misc: Extracted imgui_impl_sdl.cpp/.h away from the old combined SDL2+OpenGL/Vulkan examples. +// 2018-06-08: Misc: ImGui_ImplSDL2_InitForOpenGL() now takes a SDL_GLContext parameter. +// 2018-05-09: Misc: Fixed clipboard paste memory leak (we didn't call SDL_FreeMemory on the data returned by SDL_GetClipboardText). +// 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors flag + honor ImGuiConfigFlags_NoMouseCursorChange flag. +// 2018-02-16: Inputs: Added support for mouse cursors, honoring ImGui::GetMouseCursor() value. +// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. +// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. +// 2018-02-05: Misc: Using SDL_GetPerformanceCounter() instead of SDL_GetTicks() to be able to handle very high framerate (1000+ FPS). +// 2018-02-05: Inputs: Keyboard mapping is using scancodes everywhere instead of a confusing mixture of keycodes and scancodes. +// 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. +// 2018-01-19: Inputs: When available (SDL 2.0.4+) using SDL_CaptureMouse() to retrieve coordinates outside of client area when dragging. Otherwise (SDL 2.0.3 and before) testing for SDL_WINDOW_INPUT_FOCUS instead of SDL_WINDOW_MOUSE_FOCUS. +// 2018-01-18: Inputs: Added mapping for ImGuiKey_Insert. +// 2017-08-25: Inputs: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1). +// 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers. + +#include + +#include + +// Clang warnings with -Weverything +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision +#endif + +// SDL +// (the multi-viewports feature requires SDL features supported from SDL 2.0.4+. SDL 2.0.5+ is highly recommended) +#include +#include +#if defined(__APPLE__) +#include +#endif + +#if SDL_VERSION_ATLEAST(2,0,4) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) && !defined(__amigaos4__) +#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 1 +#else +#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 0 +#endif +#define SDL_HAS_WINDOW_ALPHA SDL_VERSION_ATLEAST(2,0,5) +#define SDL_HAS_ALWAYS_ON_TOP SDL_VERSION_ATLEAST(2,0,5) +#define SDL_HAS_USABLE_DISPLAY_BOUNDS SDL_VERSION_ATLEAST(2,0,5) +#define SDL_HAS_PER_MONITOR_DPI SDL_VERSION_ATLEAST(2,0,4) +#define SDL_HAS_VULKAN SDL_VERSION_ATLEAST(2,0,6) +#define SDL_HAS_DISPLAY_EVENT SDL_VERSION_ATLEAST(2,0,9) +#if !SDL_HAS_VULKAN +static const Uint32 SDL_WINDOW_VULKAN = 0x10000000; +#endif + +// SDL Data +struct ImGui_ImplSDL2_Data +{ + SDL_Window* Window; + SDL_Renderer* Renderer; + Uint64 Time; + Uint32 MouseWindowID; + int MouseButtonsDown; + SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT]; + SDL_Cursor* LastMouseCursor; + int PendingMouseLeaveFrame; + char* ClipboardTextData; + bool MouseCanUseGlobalState; + bool MouseCanReportHoveredViewport; // This is hard to use/unreliable on SDL so we'll set ImGuiBackendFlags_HasMouseHoveredViewport dynamically based on state. + bool UseVulkan; + bool WantUpdateMonitors; + + ImGui_ImplSDL2_Data() { memset((void*)this, 0, sizeof(*this)); } +}; + +// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts +// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. +// FIXME: multi-context support is not well tested and probably dysfunctional in this backend. +// FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context. +static ImGui_ImplSDL2_Data* ImGui_ImplSDL2_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplSDL2_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr; +} + +// Forward Declarations +static void ImGui_ImplSDL2_UpdateMonitors(); +static void ImGui_ImplSDL2_InitPlatformInterface(SDL_Window* window, void* sdl_gl_context); +static void ImGui_ImplSDL2_ShutdownPlatformInterface(); + +// Functions +static const char* ImGui_ImplSDL2_GetClipboardText(void*) +{ + ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); + if (bd->ClipboardTextData) + SDL_free(bd->ClipboardTextData); + bd->ClipboardTextData = SDL_GetClipboardText(); + return bd->ClipboardTextData; +} + +static void ImGui_ImplSDL2_SetClipboardText(void*, const char* text) +{ + SDL_SetClipboardText(text); +} + +// Note: native IME will only display if user calls SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1") _before_ SDL_CreateWindow(). +static void ImGui_ImplSDL2_SetPlatformImeData(ImGuiViewport* viewport, ImGuiPlatformImeData* data) +{ + if (data->WantVisible) + { + SDL_Rect r; + r.x = (int)(data->InputPos.x - viewport->Pos.x); + r.y = (int)(data->InputPos.y - viewport->Pos.y + data->InputLineHeight); + r.w = 1; + r.h = (int)data->InputLineHeight; + SDL_SetTextInputRect(&r); + } +} + +static ImGuiKey ImGui_ImplSDL2_KeycodeToImGuiKey(int keycode) +{ + switch (keycode) + { + case SDLK_TAB: return ImGuiKey_Tab; + case SDLK_LEFT: return ImGuiKey_LeftArrow; + case SDLK_RIGHT: return ImGuiKey_RightArrow; + case SDLK_UP: return ImGuiKey_UpArrow; + case SDLK_DOWN: return ImGuiKey_DownArrow; + case SDLK_PAGEUP: return ImGuiKey_PageUp; + case SDLK_PAGEDOWN: return ImGuiKey_PageDown; + case SDLK_HOME: return ImGuiKey_Home; + case SDLK_END: return ImGuiKey_End; + case SDLK_INSERT: return ImGuiKey_Insert; + case SDLK_DELETE: return ImGuiKey_Delete; + case SDLK_BACKSPACE: return ImGuiKey_Backspace; + case SDLK_SPACE: return ImGuiKey_Space; + case SDLK_RETURN: return ImGuiKey_Enter; + case SDLK_ESCAPE: return ImGuiKey_Escape; + case SDLK_QUOTE: return ImGuiKey_Apostrophe; + case SDLK_COMMA: return ImGuiKey_Comma; + case SDLK_MINUS: return ImGuiKey_Minus; + case SDLK_PERIOD: return ImGuiKey_Period; + case SDLK_SLASH: return ImGuiKey_Slash; + case SDLK_SEMICOLON: return ImGuiKey_Semicolon; + case SDLK_EQUALS: return ImGuiKey_Equal; + case SDLK_LEFTBRACKET: return ImGuiKey_LeftBracket; + case SDLK_BACKSLASH: return ImGuiKey_Backslash; + case SDLK_RIGHTBRACKET: return ImGuiKey_RightBracket; + case SDLK_BACKQUOTE: return ImGuiKey_GraveAccent; + case SDLK_CAPSLOCK: return ImGuiKey_CapsLock; + case SDLK_SCROLLLOCK: return ImGuiKey_ScrollLock; + case SDLK_NUMLOCKCLEAR: return ImGuiKey_NumLock; + case SDLK_PRINTSCREEN: return ImGuiKey_PrintScreen; + case SDLK_PAUSE: return ImGuiKey_Pause; + case SDLK_KP_0: return ImGuiKey_Keypad0; + case SDLK_KP_1: return ImGuiKey_Keypad1; + case SDLK_KP_2: return ImGuiKey_Keypad2; + case SDLK_KP_3: return ImGuiKey_Keypad3; + case SDLK_KP_4: return ImGuiKey_Keypad4; + case SDLK_KP_5: return ImGuiKey_Keypad5; + case SDLK_KP_6: return ImGuiKey_Keypad6; + case SDLK_KP_7: return ImGuiKey_Keypad7; + case SDLK_KP_8: return ImGuiKey_Keypad8; + case SDLK_KP_9: return ImGuiKey_Keypad9; + case SDLK_KP_PERIOD: return ImGuiKey_KeypadDecimal; + case SDLK_KP_DIVIDE: return ImGuiKey_KeypadDivide; + case SDLK_KP_MULTIPLY: return ImGuiKey_KeypadMultiply; + case SDLK_KP_MINUS: return ImGuiKey_KeypadSubtract; + case SDLK_KP_PLUS: return ImGuiKey_KeypadAdd; + case SDLK_KP_ENTER: return ImGuiKey_KeypadEnter; + case SDLK_KP_EQUALS: return ImGuiKey_KeypadEqual; + case SDLK_LCTRL: return ImGuiKey_LeftCtrl; + case SDLK_LSHIFT: return ImGuiKey_LeftShift; + case SDLK_LALT: return ImGuiKey_LeftAlt; + case SDLK_LGUI: return ImGuiKey_LeftSuper; + case SDLK_RCTRL: return ImGuiKey_RightCtrl; + case SDLK_RSHIFT: return ImGuiKey_RightShift; + case SDLK_RALT: return ImGuiKey_RightAlt; + case SDLK_RGUI: return ImGuiKey_RightSuper; + case SDLK_APPLICATION: return ImGuiKey_Menu; + case SDLK_0: return ImGuiKey_0; + case SDLK_1: return ImGuiKey_1; + case SDLK_2: return ImGuiKey_2; + case SDLK_3: return ImGuiKey_3; + case SDLK_4: return ImGuiKey_4; + case SDLK_5: return ImGuiKey_5; + case SDLK_6: return ImGuiKey_6; + case SDLK_7: return ImGuiKey_7; + case SDLK_8: return ImGuiKey_8; + case SDLK_9: return ImGuiKey_9; + case SDLK_a: return ImGuiKey_A; + case SDLK_b: return ImGuiKey_B; + case SDLK_c: return ImGuiKey_C; + case SDLK_d: return ImGuiKey_D; + case SDLK_e: return ImGuiKey_E; + case SDLK_f: return ImGuiKey_F; + case SDLK_g: return ImGuiKey_G; + case SDLK_h: return ImGuiKey_H; + case SDLK_i: return ImGuiKey_I; + case SDLK_j: return ImGuiKey_J; + case SDLK_k: return ImGuiKey_K; + case SDLK_l: return ImGuiKey_L; + case SDLK_m: return ImGuiKey_M; + case SDLK_n: return ImGuiKey_N; + case SDLK_o: return ImGuiKey_O; + case SDLK_p: return ImGuiKey_P; + case SDLK_q: return ImGuiKey_Q; + case SDLK_r: return ImGuiKey_R; + case SDLK_s: return ImGuiKey_S; + case SDLK_t: return ImGuiKey_T; + case SDLK_u: return ImGuiKey_U; + case SDLK_v: return ImGuiKey_V; + case SDLK_w: return ImGuiKey_W; + case SDLK_x: return ImGuiKey_X; + case SDLK_y: return ImGuiKey_Y; + case SDLK_z: return ImGuiKey_Z; + case SDLK_F1: return ImGuiKey_F1; + case SDLK_F2: return ImGuiKey_F2; + case SDLK_F3: return ImGuiKey_F3; + case SDLK_F4: return ImGuiKey_F4; + case SDLK_F5: return ImGuiKey_F5; + case SDLK_F6: return ImGuiKey_F6; + case SDLK_F7: return ImGuiKey_F7; + case SDLK_F8: return ImGuiKey_F8; + case SDLK_F9: return ImGuiKey_F9; + case SDLK_F10: return ImGuiKey_F10; + case SDLK_F11: return ImGuiKey_F11; + case SDLK_F12: return ImGuiKey_F12; + } + return ImGuiKey_None; +} + +static void ImGui_ImplSDL2_UpdateKeyModifiers(SDL_Keymod sdl_key_mods) +{ + ImGuiIO& io = ImGui::GetIO(); + io.AddKeyEvent(ImGuiMod_Ctrl, (sdl_key_mods & KMOD_CTRL) != 0); + io.AddKeyEvent(ImGuiMod_Shift, (sdl_key_mods & KMOD_SHIFT) != 0); + io.AddKeyEvent(ImGuiMod_Alt, (sdl_key_mods & KMOD_ALT) != 0); + io.AddKeyEvent(ImGuiMod_Super, (sdl_key_mods & KMOD_GUI) != 0); +} + +// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. +// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data. +// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data. +// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. +// If you have multiple SDL events and some of them are not meant to be used by dear imgui, you may need to filter events based on their windowID field. +bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event) +{ + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); + + switch (event->type) + { + case SDL_MOUSEMOTION: + { + ImVec2 mouse_pos((float)event->motion.x, (float)event->motion.y); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + int window_x, window_y; + SDL_GetWindowPosition(SDL_GetWindowFromID(event->motion.windowID), &window_x, &window_y); + mouse_pos.x += window_x; + mouse_pos.y += window_y; + } + io.AddMouseSourceEvent(event->motion.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse); + io.AddMousePosEvent(mouse_pos.x, mouse_pos.y); + return true; + } + case SDL_MOUSEWHEEL: + { + //IMGUI_DEBUG_LOG("wheel %.2f %.2f, precise %.2f %.2f\n", (float)event->wheel.x, (float)event->wheel.y, event->wheel.preciseX, event->wheel.preciseY); +#if SDL_VERSION_ATLEAST(2,0,18) // If this fails to compile on Emscripten: update to latest Emscripten! + float wheel_x = -event->wheel.preciseX; + float wheel_y = event->wheel.preciseY; +#else + float wheel_x = -(float)event->wheel.x; + float wheel_y = (float)event->wheel.y; +#endif +#ifdef __EMSCRIPTEN__ + wheel_x /= 100.0f; +#endif + io.AddMouseSourceEvent(event->wheel.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse); + io.AddMouseWheelEvent(wheel_x, wheel_y); + return true; + } + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + { + int mouse_button = -1; + if (event->button.button == SDL_BUTTON_LEFT) { mouse_button = 0; } + if (event->button.button == SDL_BUTTON_RIGHT) { mouse_button = 1; } + if (event->button.button == SDL_BUTTON_MIDDLE) { mouse_button = 2; } + if (event->button.button == SDL_BUTTON_X1) { mouse_button = 3; } + if (event->button.button == SDL_BUTTON_X2) { mouse_button = 4; } + if (mouse_button == -1) + break; + io.AddMouseSourceEvent(event->button.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse); + io.AddMouseButtonEvent(mouse_button, (event->type == SDL_MOUSEBUTTONDOWN)); + bd->MouseButtonsDown = (event->type == SDL_MOUSEBUTTONDOWN) ? (bd->MouseButtonsDown | (1 << mouse_button)) : (bd->MouseButtonsDown & ~(1 << mouse_button)); + return true; + } + case SDL_TEXTINPUT: + { + io.AddInputCharactersUTF8(event->text.text); + return true; + } + case SDL_KEYDOWN: + case SDL_KEYUP: + { + ImGui_ImplSDL2_UpdateKeyModifiers((SDL_Keymod)event->key.keysym.mod); + ImGuiKey key = ImGui_ImplSDL2_KeycodeToImGuiKey(event->key.keysym.sym); + io.AddKeyEvent(key, (event->type == SDL_KEYDOWN)); + io.SetKeyEventNativeData(key, event->key.keysym.sym, event->key.keysym.scancode, event->key.keysym.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions. + return true; + } +#if SDL_HAS_DISPLAY_EVENT + case SDL_DISPLAYEVENT: + { + // 2.0.26 has SDL_DISPLAYEVENT_CONNECTED/SDL_DISPLAYEVENT_DISCONNECTED/SDL_DISPLAYEVENT_ORIENTATION, + // so change of DPI/Scaling are not reflected in this event. (SDL3 has it) + bd->WantUpdateMonitors = true; + return true; + } +#endif + case SDL_WINDOWEVENT: + { + // - When capturing mouse, SDL will send a bunch of conflicting LEAVE/ENTER event on every mouse move, but the final ENTER tends to be right. + // - However we won't get a correct LEAVE event for a captured window. + // - In some cases, when detaching a window from main viewport SDL may send SDL_WINDOWEVENT_ENTER one frame too late, + // causing SDL_WINDOWEVENT_LEAVE on previous frame to interrupt drag operation by clear mouse position. This is why + // we delay process the SDL_WINDOWEVENT_LEAVE events by one frame. See issue #5012 for details. + Uint8 window_event = event->window.event; + if (window_event == SDL_WINDOWEVENT_ENTER) + { + bd->MouseWindowID = event->window.windowID; + bd->PendingMouseLeaveFrame = 0; + } + if (window_event == SDL_WINDOWEVENT_LEAVE) + bd->PendingMouseLeaveFrame = ImGui::GetFrameCount() + 1; + if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED) + io.AddFocusEvent(true); + else if (window_event == SDL_WINDOWEVENT_FOCUS_LOST) + io.AddFocusEvent(false); + if (window_event == SDL_WINDOWEVENT_CLOSE || window_event == SDL_WINDOWEVENT_MOVED || window_event == SDL_WINDOWEVENT_RESIZED) + if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)SDL_GetWindowFromID(event->window.windowID))) + { + if (window_event == SDL_WINDOWEVENT_CLOSE) + viewport->PlatformRequestClose = true; + if (window_event == SDL_WINDOWEVENT_MOVED) + viewport->PlatformRequestMove = true; + if (window_event == SDL_WINDOWEVENT_RESIZED) + viewport->PlatformRequestResize = true; + return true; + } + return true; + } + } + return false; +} + +static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void* sdl_gl_context) +{ + ImGuiIO& io = ImGui::GetIO(); + IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!"); + + // Check and store if we are on a SDL backend that supports global mouse position + // ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list) + bool mouse_can_use_global_state = false; +#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE + const char* sdl_backend = SDL_GetCurrentVideoDriver(); + const char* global_mouse_whitelist[] = { "windows", "cocoa", "x11", "DIVE", "VMAN" }; + for (int n = 0; n < IM_ARRAYSIZE(global_mouse_whitelist); n++) + if (strncmp(sdl_backend, global_mouse_whitelist[n], strlen(global_mouse_whitelist[n])) == 0) + mouse_can_use_global_state = true; +#endif + + // Setup backend capabilities flags + ImGui_ImplSDL2_Data* bd = IM_NEW(ImGui_ImplSDL2_Data)(); + io.BackendPlatformUserData = (void*)bd; + io.BackendPlatformName = "imgui_impl_sdl2"; + io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) + io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) + if (mouse_can_use_global_state) + io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional) + + bd->Window = window; + bd->Renderer = renderer; + + // SDL on Linux/OSX doesn't report events for unfocused windows (see https://github.com/ocornut/imgui/issues/4960) + // We will use 'MouseCanReportHoveredViewport' to set 'ImGuiBackendFlags_HasMouseHoveredViewport' dynamically each frame. + bd->MouseCanUseGlobalState = mouse_can_use_global_state; +#ifndef __APPLE__ + bd->MouseCanReportHoveredViewport = bd->MouseCanUseGlobalState; +#else + bd->MouseCanReportHoveredViewport = false; +#endif + bd->WantUpdateMonitors = true; + + io.SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplSDL2_GetClipboardText; + io.ClipboardUserData = nullptr; + io.SetPlatformImeDataFn = ImGui_ImplSDL2_SetPlatformImeData; + + // Load mouse cursors + bd->MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); + bd->MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); + bd->MouseCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); + bd->MouseCursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); + bd->MouseCursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); + bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); + bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE); + bd->MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND); + bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO); + + // Set platform dependent data in viewport + // Our mouse update function expect PlatformHandle to be filled for the main viewport + ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + main_viewport->PlatformHandle = (void*)window; + main_viewport->PlatformHandleRaw = nullptr; + SDL_SysWMinfo info; + SDL_VERSION(&info.version); + if (SDL_GetWindowWMInfo(window, &info)) + { +#if defined(SDL_VIDEO_DRIVER_WINDOWS) + main_viewport->PlatformHandleRaw = (void*)info.info.win.window; +#elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA) + main_viewport->PlatformHandleRaw = (void*)info.info.cocoa.window; +#endif + } + + // From 2.0.5: Set SDL hint to receive mouse click events on window focus, otherwise SDL doesn't emit the event. + // Without this, when clicking to gain focus, our widgets wouldn't activate even though they showed as hovered. + // (This is unfortunately a global SDL setting, so enabling it might have a side-effect on your application. + // It is unlikely to make a difference, but if your app absolutely needs to ignore the initial on-focus click: + // you can ignore SDL_MOUSEBUTTONDOWN events coming right after a SDL_WINDOWEVENT_FOCUS_GAINED) +#ifdef SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH + SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); +#endif + + // From 2.0.18: Enable native IME. + // IMPORTANT: This is used at the time of SDL_CreateWindow() so this will only affects secondary windows, if any. + // For the main window to be affected, your application needs to call this manually before calling SDL_CreateWindow(). +#ifdef SDL_HINT_IME_SHOW_UI + SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1"); +#endif + + // From 2.0.22: Disable auto-capture, this is preventing drag and drop across multiple windows (see #5710) +#ifdef SDL_HINT_MOUSE_AUTO_CAPTURE + SDL_SetHint(SDL_HINT_MOUSE_AUTO_CAPTURE, "0"); +#endif + + // We need SDL_CaptureMouse(), SDL_GetGlobalMouseState() from SDL 2.0.4+ to support multiple viewports. + // We left the call to ImGui_ImplSDL2_InitPlatformInterface() outside of #ifdef to avoid unused-function warnings. + if ((io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) && (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports)) + ImGui_ImplSDL2_InitPlatformInterface(window, sdl_gl_context); + + return true; +} + +bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context) +{ + return ImGui_ImplSDL2_Init(window, nullptr, sdl_gl_context); +} + +bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window) +{ +#if !SDL_HAS_VULKAN + IM_ASSERT(0 && "Unsupported"); +#endif + if (!ImGui_ImplSDL2_Init(window, nullptr, nullptr)) + return false; + ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); + bd->UseVulkan = true; + return true; +} + +bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window) +{ +#if !defined(_WIN32) + IM_ASSERT(0 && "Unsupported"); +#endif + return ImGui_ImplSDL2_Init(window, nullptr, nullptr); +} + +bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window) +{ + return ImGui_ImplSDL2_Init(window, nullptr, nullptr); +} + +bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer) +{ + return ImGui_ImplSDL2_Init(window, renderer, nullptr); +} + +void ImGui_ImplSDL2_Shutdown() +{ + ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); + IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?"); + ImGuiIO& io = ImGui::GetIO(); + + ImGui_ImplSDL2_ShutdownPlatformInterface(); + + if (bd->ClipboardTextData) + SDL_free(bd->ClipboardTextData); + for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++) + SDL_FreeCursor(bd->MouseCursors[cursor_n]); + bd->LastMouseCursor = nullptr; + + io.BackendPlatformName = nullptr; + io.BackendPlatformUserData = nullptr; + io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport); + IM_DELETE(bd); +} + +// This code is incredibly messy because some of the functions we need for full viewport support are not available in SDL < 2.0.4. +static void ImGui_ImplSDL2_UpdateMouseData() +{ + ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); + ImGuiIO& io = ImGui::GetIO(); + + // We forward mouse input when hovered or captured (via SDL_MOUSEMOTION) or when focused (below) +#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE + // SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger other operations outside + SDL_CaptureMouse((bd->MouseButtonsDown != 0) ? SDL_TRUE : SDL_FALSE); + SDL_Window* focused_window = SDL_GetKeyboardFocus(); + const bool is_app_focused = (focused_window && (bd->Window == focused_window || ImGui::FindViewportByPlatformHandle((void*)focused_window))); +#else + SDL_Window* focused_window = bd->Window; + const bool is_app_focused = (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_INPUT_FOCUS) != 0; // SDL 2.0.3 and non-windowed systems: single-viewport only +#endif + + if (is_app_focused) + { + // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) + if (io.WantSetMousePos) + { +#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + SDL_WarpMouseGlobal((int)io.MousePos.x, (int)io.MousePos.y); + else +#endif + SDL_WarpMouseInWindow(bd->Window, (int)io.MousePos.x, (int)io.MousePos.y); + } + + // (Optional) Fallback to provide mouse position when focused (SDL_MOUSEMOTION already provides this when hovered or captured) + if (bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0) + { + // Single-viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window) + // Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor) + int mouse_x, mouse_y, window_x, window_y; + SDL_GetGlobalMouseState(&mouse_x, &mouse_y); + if (!(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)) + { + SDL_GetWindowPosition(focused_window, &window_x, &window_y); + mouse_x -= window_x; + mouse_y -= window_y; + } + io.AddMousePosEvent((float)mouse_x, (float)mouse_y); + } + } + + // (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is hovering. + // If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear imGui will ignore this field and infer the information using its flawed heuristic. + // - [!] SDL backend does NOT correctly ignore viewports with the _NoInputs flag. + // Some backend are not able to handle that correctly. If a backend report an hovered viewport that has the _NoInputs flag (e.g. when dragging a window + // for docking, the viewport has the _NoInputs flag in order to allow us to find the viewport under), then Dear ImGui is forced to ignore the value reported + // by the backend, and use its flawed heuristic to guess the viewport behind. + // - [X] SDL backend correctly reports this regardless of another viewport behind focused and dragged from (we need this to find a useful drag and drop target). + if (io.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport) + { + ImGuiID mouse_viewport_id = 0; + if (SDL_Window* sdl_mouse_window = SDL_GetWindowFromID(bd->MouseWindowID)) + if (ImGuiViewport* mouse_viewport = ImGui::FindViewportByPlatformHandle((void*)sdl_mouse_window)) + mouse_viewport_id = mouse_viewport->ID; + io.AddMouseViewportEvent(mouse_viewport_id); + } +} + +static void ImGui_ImplSDL2_UpdateMouseCursor() +{ + ImGuiIO& io = ImGui::GetIO(); + if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) + return; + ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); + + ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor(); + if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None) + { + // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor + SDL_ShowCursor(SDL_FALSE); + } + else + { + // Show OS mouse cursor + SDL_Cursor* expected_cursor = bd->MouseCursors[imgui_cursor] ? bd->MouseCursors[imgui_cursor] : bd->MouseCursors[ImGuiMouseCursor_Arrow]; + if (bd->LastMouseCursor != expected_cursor) + { + SDL_SetCursor(expected_cursor); // SDL function doesn't have an early out (see #6113) + bd->LastMouseCursor = expected_cursor; + } + SDL_ShowCursor(SDL_TRUE); + } +} + +static void ImGui_ImplSDL2_UpdateGamepads() +{ + ImGuiIO& io = ImGui::GetIO(); + if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) // FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs. + return; + + // Get gamepad + io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; + SDL_GameController* game_controller = SDL_GameControllerOpen(0); + if (!game_controller) + return; + io.BackendFlags |= ImGuiBackendFlags_HasGamepad; + + // Update gamepad inputs + #define IM_SATURATE(V) (V < 0.0f ? 0.0f : V > 1.0f ? 1.0f : V) + #define MAP_BUTTON(KEY_NO, BUTTON_NO) { io.AddKeyEvent(KEY_NO, SDL_GameControllerGetButton(game_controller, BUTTON_NO) != 0); } + #define MAP_ANALOG(KEY_NO, AXIS_NO, V0, V1) { float vn = (float)(SDL_GameControllerGetAxis(game_controller, AXIS_NO) - V0) / (float)(V1 - V0); vn = IM_SATURATE(vn); io.AddKeyAnalogEvent(KEY_NO, vn > 0.1f, vn); } + const int thumb_dead_zone = 8000; // SDL_gamecontroller.h suggests using this value. + MAP_BUTTON(ImGuiKey_GamepadStart, SDL_CONTROLLER_BUTTON_START); + MAP_BUTTON(ImGuiKey_GamepadBack, SDL_CONTROLLER_BUTTON_BACK); + MAP_BUTTON(ImGuiKey_GamepadFaceLeft, SDL_CONTROLLER_BUTTON_X); // Xbox X, PS Square + MAP_BUTTON(ImGuiKey_GamepadFaceRight, SDL_CONTROLLER_BUTTON_B); // Xbox B, PS Circle + MAP_BUTTON(ImGuiKey_GamepadFaceUp, SDL_CONTROLLER_BUTTON_Y); // Xbox Y, PS Triangle + MAP_BUTTON(ImGuiKey_GamepadFaceDown, SDL_CONTROLLER_BUTTON_A); // Xbox A, PS Cross + MAP_BUTTON(ImGuiKey_GamepadDpadLeft, SDL_CONTROLLER_BUTTON_DPAD_LEFT); + MAP_BUTTON(ImGuiKey_GamepadDpadRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT); + MAP_BUTTON(ImGuiKey_GamepadDpadUp, SDL_CONTROLLER_BUTTON_DPAD_UP); + MAP_BUTTON(ImGuiKey_GamepadDpadDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN); + MAP_BUTTON(ImGuiKey_GamepadL1, SDL_CONTROLLER_BUTTON_LEFTSHOULDER); + MAP_BUTTON(ImGuiKey_GamepadR1, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); + MAP_ANALOG(ImGuiKey_GamepadL2, SDL_CONTROLLER_AXIS_TRIGGERLEFT, 0.0f, 32767); + MAP_ANALOG(ImGuiKey_GamepadR2, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, 0.0f, 32767); + MAP_BUTTON(ImGuiKey_GamepadL3, SDL_CONTROLLER_BUTTON_LEFTSTICK); + MAP_BUTTON(ImGuiKey_GamepadR3, SDL_CONTROLLER_BUTTON_RIGHTSTICK); + MAP_ANALOG(ImGuiKey_GamepadLStickLeft, SDL_CONTROLLER_AXIS_LEFTX, -thumb_dead_zone, -32768); + MAP_ANALOG(ImGuiKey_GamepadLStickRight, SDL_CONTROLLER_AXIS_LEFTX, +thumb_dead_zone, +32767); + MAP_ANALOG(ImGuiKey_GamepadLStickUp, SDL_CONTROLLER_AXIS_LEFTY, -thumb_dead_zone, -32768); + MAP_ANALOG(ImGuiKey_GamepadLStickDown, SDL_CONTROLLER_AXIS_LEFTY, +thumb_dead_zone, +32767); + MAP_ANALOG(ImGuiKey_GamepadRStickLeft, SDL_CONTROLLER_AXIS_RIGHTX, -thumb_dead_zone, -32768); + MAP_ANALOG(ImGuiKey_GamepadRStickRight, SDL_CONTROLLER_AXIS_RIGHTX, +thumb_dead_zone, +32767); + MAP_ANALOG(ImGuiKey_GamepadRStickUp, SDL_CONTROLLER_AXIS_RIGHTY, -thumb_dead_zone, -32768); + MAP_ANALOG(ImGuiKey_GamepadRStickDown, SDL_CONTROLLER_AXIS_RIGHTY, +thumb_dead_zone, +32767); + #undef MAP_BUTTON + #undef MAP_ANALOG +} + +// FIXME: Note that doesn't update with DPI/Scaling change only as SDL2 doesn't have an event for it (SDL3 has). +static void ImGui_ImplSDL2_UpdateMonitors() +{ + ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + platform_io.Monitors.resize(0); + bd->WantUpdateMonitors = false; + int display_count = SDL_GetNumVideoDisplays(); + for (int n = 0; n < display_count; n++) + { + // Warning: the validity of monitor DPI information on Windows depends on the application DPI awareness settings, which generally needs to be set in the manifest or at runtime. + ImGuiPlatformMonitor monitor; + SDL_Rect r; + SDL_GetDisplayBounds(n, &r); + monitor.MainPos = monitor.WorkPos = ImVec2((float)r.x, (float)r.y); + monitor.MainSize = monitor.WorkSize = ImVec2((float)r.w, (float)r.h); +#if SDL_HAS_USABLE_DISPLAY_BOUNDS + SDL_GetDisplayUsableBounds(n, &r); + monitor.WorkPos = ImVec2((float)r.x, (float)r.y); + monitor.WorkSize = ImVec2((float)r.w, (float)r.h); +#endif +#if SDL_HAS_PER_MONITOR_DPI + // FIXME-VIEWPORT: On MacOS SDL reports actual monitor DPI scale, ignoring OS configuration. We may want to set + // DpiScale to cocoa_window.backingScaleFactor here. + float dpi = 0.0f; + if (!SDL_GetDisplayDPI(n, &dpi, nullptr, nullptr)) + monitor.DpiScale = dpi / 96.0f; +#endif + monitor.PlatformHandle = (void*)(intptr_t)n; + platform_io.Monitors.push_back(monitor); + } +} + +void ImGui_ImplSDL2_NewFrame() +{ + ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); + IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplSDL2_Init()?"); + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + SDL_GetWindowSize(bd->Window, &w, &h); + if (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_MINIMIZED) + w = h = 0; + if (bd->Renderer != nullptr) + SDL_GetRendererOutputSize(bd->Renderer, &display_w, &display_h); + else + SDL_GL_GetDrawableSize(bd->Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + if (w > 0 && h > 0) + io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h); + + // Update monitors + if (bd->WantUpdateMonitors) + ImGui_ImplSDL2_UpdateMonitors(); + + // Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution) + // (Accept SDL_GetPerformanceCounter() not returning a monotonically increasing value. Happens in VMs and Emscripten, see #6189, #6114, #3644) + static Uint64 frequency = SDL_GetPerformanceFrequency(); + Uint64 current_time = SDL_GetPerformanceCounter(); + if (current_time <= bd->Time) + current_time = bd->Time + 1; + io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f); + bd->Time = current_time; + + if (bd->PendingMouseLeaveFrame && bd->PendingMouseLeaveFrame >= ImGui::GetFrameCount() && bd->MouseButtonsDown == 0) + { + bd->MouseWindowID = 0; + bd->PendingMouseLeaveFrame = 0; + io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); + } + + // Our io.AddMouseViewportEvent() calls will only be valid when not capturing. + // Technically speaking testing for 'bd->MouseButtonsDown == 0' would be more rygorous, but testing for payload reduces noise and potential side-effects. + if (bd->MouseCanReportHoveredViewport && ImGui::GetDragDropPayload() == nullptr) + io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; + else + io.BackendFlags &= ~ImGuiBackendFlags_HasMouseHoveredViewport; + + ImGui_ImplSDL2_UpdateMouseData(); + ImGui_ImplSDL2_UpdateMouseCursor(); + + // Update game controllers (if enabled and available) + ImGui_ImplSDL2_UpdateGamepads(); +} + +//-------------------------------------------------------------------------------------------------------- +// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT +// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously. +// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first.. +//-------------------------------------------------------------------------------------------------------- + +// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our backend data. +struct ImGui_ImplSDL2_ViewportData +{ + SDL_Window* Window; + Uint32 WindowID; + bool WindowOwned; + SDL_GLContext GLContext; + + ImGui_ImplSDL2_ViewportData() { Window = nullptr; WindowID = 0; WindowOwned = false; GLContext = nullptr; } + ~ImGui_ImplSDL2_ViewportData() { IM_ASSERT(Window == nullptr && GLContext == nullptr); } +}; + +static void ImGui_ImplSDL2_CreateWindow(ImGuiViewport* viewport) +{ + ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); + ImGui_ImplSDL2_ViewportData* vd = IM_NEW(ImGui_ImplSDL2_ViewportData)(); + viewport->PlatformUserData = vd; + + ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + ImGui_ImplSDL2_ViewportData* main_viewport_data = (ImGui_ImplSDL2_ViewportData*)main_viewport->PlatformUserData; + + // Share GL resources with main context + bool use_opengl = (main_viewport_data->GLContext != nullptr); + SDL_GLContext backup_context = nullptr; + if (use_opengl) + { + backup_context = SDL_GL_GetCurrentContext(); + SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1); + SDL_GL_MakeCurrent(main_viewport_data->Window, main_viewport_data->GLContext); + } + + Uint32 sdl_flags = 0; + sdl_flags |= use_opengl ? SDL_WINDOW_OPENGL : (bd->UseVulkan ? SDL_WINDOW_VULKAN : 0); + sdl_flags |= SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_ALLOW_HIGHDPI; + sdl_flags |= SDL_WINDOW_HIDDEN; + sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? SDL_WINDOW_BORDERLESS : 0; + sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? 0 : SDL_WINDOW_RESIZABLE; +#if !defined(_WIN32) + // See SDL hack in ImGui_ImplSDL2_ShowWindow(). + sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon) ? SDL_WINDOW_SKIP_TASKBAR : 0; +#endif +#if SDL_HAS_ALWAYS_ON_TOP + sdl_flags |= (viewport->Flags & ImGuiViewportFlags_TopMost) ? SDL_WINDOW_ALWAYS_ON_TOP : 0; +#endif + vd->Window = SDL_CreateWindow("No Title Yet", (int)viewport->Pos.x, (int)viewport->Pos.y, (int)viewport->Size.x, (int)viewport->Size.y, sdl_flags); + vd->WindowOwned = true; + if (use_opengl) + { + vd->GLContext = SDL_GL_CreateContext(vd->Window); + SDL_GL_SetSwapInterval(0); + } + if (use_opengl && backup_context) + SDL_GL_MakeCurrent(vd->Window, backup_context); + + viewport->PlatformHandle = (void*)vd->Window; + viewport->PlatformHandleRaw = nullptr; + SDL_SysWMinfo info; + SDL_VERSION(&info.version); + if (SDL_GetWindowWMInfo(vd->Window, &info)) + { +#if defined(SDL_VIDEO_DRIVER_WINDOWS) + viewport->PlatformHandleRaw = info.info.win.window; +#elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA) + viewport->PlatformHandleRaw = (void*)info.info.cocoa.window; +#endif + } +} + +static void ImGui_ImplSDL2_DestroyWindow(ImGuiViewport* viewport) +{ + if (ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData) + { + if (vd->GLContext && vd->WindowOwned) + SDL_GL_DeleteContext(vd->GLContext); + if (vd->Window && vd->WindowOwned) + SDL_DestroyWindow(vd->Window); + vd->GLContext = nullptr; + vd->Window = nullptr; + IM_DELETE(vd); + } + viewport->PlatformUserData = viewport->PlatformHandle = nullptr; +} + +static void ImGui_ImplSDL2_ShowWindow(ImGuiViewport* viewport) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; +#if defined(_WIN32) + HWND hwnd = (HWND)viewport->PlatformHandleRaw; + + // SDL hack: Hide icon from task bar + // Note: SDL 2.0.6+ has a SDL_WINDOW_SKIP_TASKBAR flag which is supported under Windows but the way it create the window breaks our seamless transition. + if (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon) + { + LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE); + ex_style &= ~WS_EX_APPWINDOW; + ex_style |= WS_EX_TOOLWINDOW; + ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style); + } + + // SDL hack: SDL always activate/focus windows :/ + if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing) + { + ::ShowWindow(hwnd, SW_SHOWNA); + return; + } +#endif + + SDL_ShowWindow(vd->Window); +} + +static ImVec2 ImGui_ImplSDL2_GetWindowPos(ImGuiViewport* viewport) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + int x = 0, y = 0; + SDL_GetWindowPosition(vd->Window, &x, &y); + return ImVec2((float)x, (float)y); +} + +static void ImGui_ImplSDL2_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + SDL_SetWindowPosition(vd->Window, (int)pos.x, (int)pos.y); +} + +static ImVec2 ImGui_ImplSDL2_GetWindowSize(ImGuiViewport* viewport) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + int w = 0, h = 0; + SDL_GetWindowSize(vd->Window, &w, &h); + return ImVec2((float)w, (float)h); +} + +static void ImGui_ImplSDL2_SetWindowSize(ImGuiViewport* viewport, ImVec2 size) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + SDL_SetWindowSize(vd->Window, (int)size.x, (int)size.y); +} + +static void ImGui_ImplSDL2_SetWindowTitle(ImGuiViewport* viewport, const char* title) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + SDL_SetWindowTitle(vd->Window, title); +} + +#if SDL_HAS_WINDOW_ALPHA +static void ImGui_ImplSDL2_SetWindowAlpha(ImGuiViewport* viewport, float alpha) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + SDL_SetWindowOpacity(vd->Window, alpha); +} +#endif + +static void ImGui_ImplSDL2_SetWindowFocus(ImGuiViewport* viewport) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + SDL_RaiseWindow(vd->Window); +} + +static bool ImGui_ImplSDL2_GetWindowFocus(ImGuiViewport* viewport) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + return (SDL_GetWindowFlags(vd->Window) & SDL_WINDOW_INPUT_FOCUS) != 0; +} + +static bool ImGui_ImplSDL2_GetWindowMinimized(ImGuiViewport* viewport) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + return (SDL_GetWindowFlags(vd->Window) & SDL_WINDOW_MINIMIZED) != 0; +} + +static void ImGui_ImplSDL2_RenderWindow(ImGuiViewport* viewport, void*) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + if (vd->GLContext) + SDL_GL_MakeCurrent(vd->Window, vd->GLContext); +} + +static void ImGui_ImplSDL2_SwapBuffers(ImGuiViewport* viewport, void*) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + if (vd->GLContext) + { + SDL_GL_MakeCurrent(vd->Window, vd->GLContext); + SDL_GL_SwapWindow(vd->Window); + } +} + +// Vulkan support (the Vulkan renderer needs to call a platform-side support function to create the surface) +// SDL is graceful enough to _not_ need so we can safely include this. +#if SDL_HAS_VULKAN +#include +static int ImGui_ImplSDL2_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_instance, const void* vk_allocator, ImU64* out_vk_surface) +{ + ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; + (void)vk_allocator; + SDL_bool ret = SDL_Vulkan_CreateSurface(vd->Window, (VkInstance)vk_instance, (VkSurfaceKHR*)out_vk_surface); + return ret ? 0 : 1; // ret ? VK_SUCCESS : VK_NOT_READY +} +#endif // SDL_HAS_VULKAN + +static void ImGui_ImplSDL2_InitPlatformInterface(SDL_Window* window, void* sdl_gl_context) +{ + // Register platform interface (will be coupled with a renderer interface) + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + platform_io.Platform_CreateWindow = ImGui_ImplSDL2_CreateWindow; + platform_io.Platform_DestroyWindow = ImGui_ImplSDL2_DestroyWindow; + platform_io.Platform_ShowWindow = ImGui_ImplSDL2_ShowWindow; + platform_io.Platform_SetWindowPos = ImGui_ImplSDL2_SetWindowPos; + platform_io.Platform_GetWindowPos = ImGui_ImplSDL2_GetWindowPos; + platform_io.Platform_SetWindowSize = ImGui_ImplSDL2_SetWindowSize; + platform_io.Platform_GetWindowSize = ImGui_ImplSDL2_GetWindowSize; + platform_io.Platform_SetWindowFocus = ImGui_ImplSDL2_SetWindowFocus; + platform_io.Platform_GetWindowFocus = ImGui_ImplSDL2_GetWindowFocus; + platform_io.Platform_GetWindowMinimized = ImGui_ImplSDL2_GetWindowMinimized; + platform_io.Platform_SetWindowTitle = ImGui_ImplSDL2_SetWindowTitle; + platform_io.Platform_RenderWindow = ImGui_ImplSDL2_RenderWindow; + platform_io.Platform_SwapBuffers = ImGui_ImplSDL2_SwapBuffers; +#if SDL_HAS_WINDOW_ALPHA + platform_io.Platform_SetWindowAlpha = ImGui_ImplSDL2_SetWindowAlpha; +#endif +#if SDL_HAS_VULKAN + platform_io.Platform_CreateVkSurface = ImGui_ImplSDL2_CreateVkSurface; +#endif + + // Register main window handle (which is owned by the main application, not by us) + // This is mostly for simplicity and consistency, so that our code (e.g. mouse handling etc.) can use same logic for main and secondary viewports. + ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + ImGui_ImplSDL2_ViewportData* vd = IM_NEW(ImGui_ImplSDL2_ViewportData)(); + vd->Window = window; + vd->WindowID = SDL_GetWindowID(window); + vd->WindowOwned = false; + vd->GLContext = sdl_gl_context; + main_viewport->PlatformUserData = vd; + main_viewport->PlatformHandle = vd->Window; +} + +static void ImGui_ImplSDL2_ShutdownPlatformInterface() +{ + ImGui::DestroyPlatformWindows(); +} + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif diff --git a/vendor/imgui-backends/src/sdlrenderer2.cpp b/vendor/imgui-backends/src/sdlrenderer2.cpp new file mode 100644 index 0000000..6e51974 --- /dev/null +++ b/vendor/imgui-backends/src/sdlrenderer2.cpp @@ -0,0 +1,265 @@ +// dear imgui: Renderer Backend for SDL_Renderer for SDL2 +// (Requires: SDL 2.0.17+) + +// Note how SDL_Renderer is an _optional_ component of SDL2. +// For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX. +// If your application will want to render any non trivial amount of graphics other than UI, +// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user and +// it might be difficult to step out of those boundaries. + +// Implemented features: +// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID! +// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. +// Missing features: +// [ ] Renderer: Multi-viewport support (multiple windows). + +// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. +// Read online: https://github.com/ocornut/imgui/tree/master/docs + +// CHANGELOG +// 2023-05-30: Renamed imgui_impl_sdlrenderer.h/.cpp to imgui_impl_sdlrenderer2.h/.cpp to accommodate for upcoming SDL3. +// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. +// 2021-12-21: Update SDL_RenderGeometryRaw() format to work with SDL 2.0.19. +// 2021-12-03: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. +// 2021-10-06: Backup and restore modified ClipRect/Viewport. +// 2021-09-21: Initial version. + +#include + +#include + +#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier +#include // intptr_t +#else +#include // intptr_t +#endif + +// Clang warnings with -Weverything +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness +#endif + +// SDL +#include +#if !SDL_VERSION_ATLEAST(2,0,17) +#error This backend requires SDL 2.0.17+ because of SDL_RenderGeometry() function +#endif + +// SDL_Renderer data +struct ImGui_ImplSDLRenderer2_Data +{ + SDL_Renderer* SDLRenderer; + SDL_Texture* FontTexture; + ImGui_ImplSDLRenderer2_Data() { memset((void*)this, 0, sizeof(*this)); } +}; + +// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts +// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. +static ImGui_ImplSDLRenderer2_Data* ImGui_ImplSDLRenderer2_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplSDLRenderer2_Data*)ImGui::GetIO().BackendRendererUserData : nullptr; +} + +// Functions +bool ImGui_ImplSDLRenderer2_Init(SDL_Renderer* renderer) +{ + ImGuiIO& io = ImGui::GetIO(); + IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); + IM_ASSERT(renderer != nullptr && "SDL_Renderer not initialized!"); + + // Setup backend capabilities flags + ImGui_ImplSDLRenderer2_Data* bd = IM_NEW(ImGui_ImplSDLRenderer2_Data)(); + io.BackendRendererUserData = (void*)bd; + io.BackendRendererName = "imgui_impl_sdlrenderer2"; + io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. + + bd->SDLRenderer = renderer; + + return true; +} + +void ImGui_ImplSDLRenderer2_Shutdown() +{ + ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData(); + IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?"); + ImGuiIO& io = ImGui::GetIO(); + + ImGui_ImplSDLRenderer2_DestroyDeviceObjects(); + + io.BackendRendererName = nullptr; + io.BackendRendererUserData = nullptr; + io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset; + IM_DELETE(bd); +} + +static void ImGui_ImplSDLRenderer2_SetupRenderState() +{ + ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData(); + + // Clear out any viewports and cliprect set by the user + // FIXME: Technically speaking there are lots of other things we could backup/setup/restore during our render process. + SDL_RenderSetViewport(bd->SDLRenderer, nullptr); + SDL_RenderSetClipRect(bd->SDLRenderer, nullptr); +} + +void ImGui_ImplSDLRenderer2_NewFrame() +{ + ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData(); + IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplSDLRenderer2_Init()?"); + + if (!bd->FontTexture) + ImGui_ImplSDLRenderer2_CreateDeviceObjects(); +} + +void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data) +{ + ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData(); + + // If there's a scale factor set by the user, use that instead + // If the user has specified a scale factor to SDL_Renderer already via SDL_RenderSetScale(), SDL will scale whatever we pass + // to SDL_RenderGeometryRaw() by that scale factor. In that case we don't want to be also scaling it ourselves here. + float rsx = 1.0f; + float rsy = 1.0f; + SDL_RenderGetScale(bd->SDLRenderer, &rsx, &rsy); + ImVec2 render_scale; + render_scale.x = (rsx == 1.0f) ? draw_data->FramebufferScale.x : 1.0f; + render_scale.y = (rsy == 1.0f) ? draw_data->FramebufferScale.y : 1.0f; + + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + int fb_width = (int)(draw_data->DisplaySize.x * render_scale.x); + int fb_height = (int)(draw_data->DisplaySize.y * render_scale.y); + if (fb_width == 0 || fb_height == 0) + return; + + // Backup SDL_Renderer state that will be modified to restore it afterwards + struct BackupSDLRendererState + { + SDL_Rect Viewport; + bool ClipEnabled; + SDL_Rect ClipRect; + }; + BackupSDLRendererState old = {}; + old.ClipEnabled = SDL_RenderIsClipEnabled(bd->SDLRenderer) == SDL_TRUE; + SDL_RenderGetViewport(bd->SDLRenderer, &old.Viewport); + SDL_RenderGetClipRect(bd->SDLRenderer, &old.ClipRect); + + // Will project scissor/clipping rectangles into framebuffer space + ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports + ImVec2 clip_scale = render_scale; + + // Render command lists + ImGui_ImplSDLRenderer2_SetupRenderState(); + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; + const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + // User callback, registered via ImDrawList::AddCallback() + // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) + if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) + ImGui_ImplSDLRenderer2_SetupRenderState(); + else + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + // Project scissor/clipping rectangles into framebuffer space + ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y); + ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y); + if (clip_min.x < 0.0f) { clip_min.x = 0.0f; } + if (clip_min.y < 0.0f) { clip_min.y = 0.0f; } + if (clip_max.x > (float)fb_width) { clip_max.x = (float)fb_width; } + if (clip_max.y > (float)fb_height) { clip_max.y = (float)fb_height; } + if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) + continue; + + SDL_Rect r = { (int)(clip_min.x), (int)(clip_min.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y) }; + SDL_RenderSetClipRect(bd->SDLRenderer, &r); + + const float* xy = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, pos)); + const float* uv = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, uv)); +#if SDL_VERSION_ATLEAST(2,0,19) + const SDL_Color* color = (const SDL_Color*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, col)); // SDL 2.0.19+ +#else + const int* color = (const int*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, col)); // SDL 2.0.17 and 2.0.18 +#endif + + // Bind texture, Draw + SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID(); + SDL_RenderGeometryRaw(bd->SDLRenderer, tex, + xy, (int)sizeof(ImDrawVert), + color, (int)sizeof(ImDrawVert), + uv, (int)sizeof(ImDrawVert), + cmd_list->VtxBuffer.Size - pcmd->VtxOffset, + idx_buffer + pcmd->IdxOffset, pcmd->ElemCount, sizeof(ImDrawIdx)); + } + } + } + + // Restore modified SDL_Renderer state + SDL_RenderSetViewport(bd->SDLRenderer, &old.Viewport); + SDL_RenderSetClipRect(bd->SDLRenderer, old.ClipEnabled ? &old.ClipRect : nullptr); +} + +// Called by Init/NewFrame/Shutdown +bool ImGui_ImplSDLRenderer2_CreateFontsTexture() +{ + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData(); + + // Build texture atlas + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory. + + // Upload texture to graphics system + // (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling) + bd->FontTexture = SDL_CreateTexture(bd->SDLRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STATIC, width, height); + if (bd->FontTexture == nullptr) + { + SDL_Log("error creating texture"); + return false; + } + SDL_UpdateTexture(bd->FontTexture, nullptr, pixels, 4 * width); + SDL_SetTextureBlendMode(bd->FontTexture, SDL_BLENDMODE_BLEND); + SDL_SetTextureScaleMode(bd->FontTexture, SDL_ScaleModeLinear); + + // Store our identifier + io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontTexture); + + return true; +} + +void ImGui_ImplSDLRenderer2_DestroyFontsTexture() +{ + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData(); + if (bd->FontTexture) + { + io.Fonts->SetTexID(0); + SDL_DestroyTexture(bd->FontTexture); + bd->FontTexture = nullptr; + } +} + +bool ImGui_ImplSDLRenderer2_CreateDeviceObjects() +{ + return ImGui_ImplSDLRenderer2_CreateFontsTexture(); +} + +void ImGui_ImplSDLRenderer2_DestroyDeviceObjects() +{ + ImGui_ImplSDLRenderer2_DestroyFontsTexture(); +} + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif diff --git a/xmake.lua b/xmake.lua index eeeab46..b9f70a7 100644 --- a/xmake.lua +++ b/xmake.lua @@ -1,11 +1,12 @@ -set_xmakever("2.7.2") +set_xmakever("2.8.1") + +includes("vendor/FeldarianBaseLibrary") set_allowedplats("windows") set_arch("x64") set_languages("cxx20") -add_rules("mode.debug", "mode.releasedbg", "mode.release") add_rules("plugin.vsxmake.autoupdate") add_rules("c.unity_build") add_rules("c++.unity_build") @@ -13,8 +14,9 @@ add_rules("c++.unity_build") add_defines("UNICODE=1", "_UNICODE=1") if (is_plat("windows")) then - add_cxflags("/bigobj", "/MP", "/utf-8") - add_defines("_CRT_SECURE_NO_WARNINGS=1", "WIN32_LEAN_AND_MEAN=1", "NOMINMAX=1", "WINVER=_WIN32_WINNT_WIN10", "_WIN32_WINNT=_WIN32_WINNT_WIN10", "NTDDI=NTDDI_WIN10_19H1", "ENABLE_SNDFILE_WINDOWS_PROTOTYPES=1") + add_cxflags("/bigobj", "/utf-8", {tools = {"clang_cl", "cl"}}) + add_cxflags("/MP", {tools = {"cl"}}) + add_defines("_CRT_SECURE_NO_WARNINGS=1", "WIN32_LEAN_AND_MEAN=1", "NOMINMAX=1", "WINVER=_WIN32_WINNT_WIN10", "_WIN32_WINNT=_WIN32_WINNT_WIN10", "NTDDI=NTDDI_WIN10_19H1") end local vsRuntime = "MD" @@ -25,6 +27,10 @@ if is_mode("debug") then set_optimize("none") set_warnings("all") set_policy("build.optimization.lto", false) + + --add_cxflags("/fsanitize=address") + --add_mxflags("/fsanitize=address") + --add_ldflags("/fsanitize=address") vsRuntime = vsRuntime.."d" elseif is_mode("releasedbg") then @@ -33,6 +39,10 @@ elseif is_mode("releasedbg") then set_optimize("fastest") set_warnings("all") set_policy("build.optimization.lto", true) + + --add_cxflags("/fsanitize=address") + --add_mxflags("/fsanitize=address") + --add_ldflags("/fsanitize=address") vsRuntime = vsRuntime.."d" elseif is_mode("release") then @@ -40,28 +50,26 @@ elseif is_mode("release") then set_symbols("hidden") set_strip("all") set_optimize("fastest") - set_warnings("all", "error") + set_warnings("all")--, "error") set_policy("build.optimization.lto", true) end set_runtimes(vsRuntime); -set_toolchains("clang-cl", "msvc", {vs = "2022"}) -add_cxflags("-Wno-unused-command-line-argument", "-Wno-pragma-system-header-outside-header") -- this line should be enabled only when using clang-cl +add_cxflags("-Wno-microsoft-include", "-Wno-unused-command-line-argument", "-Wno-pragma-system-header-outside-header", {tools = {"clang_cl", "clang"}}) -add_defines("IMGUI_DISABLE_OBSOLETE_FUNCTIONS=1", "GL_GLEXT_PROTOTYPES=1", "TOML_EXCEPTIONS=0") +add_defines("IMGUI_DISABLE_OBSOLETE_FUNCTIONS=1") add_requireconfs("*", { configs = { debug = is_mode("debug"), lto = not is_mode("debug"), shared = false, vs_runtime = vsRuntime } }) add_requires("scnlib 1.1.2", { configs = { header_only = false } }) -add_requires("libsdl 2.28.0", { configs = { shared = true, use_sdlmain = true } }) -add_requires("libsndfile 1.2.0", { configs = { shared = true } }) -add_requires("xxhash v0.8.1") ---add_requires("toml++ 3.3.0", { configs = { header_only = true } }) -- 3.3.0 misses important patch for us, wait for newer version which contains fix from master or make a fork... -add_requires("toml++ master", { configs = { header_only = true } }) +add_requires("libsdl 2.28.1", { configs = { shared = true, use_sdlmain = false } }) +add_requires("spdlog v1.12.0", { configs = { header_only = true, std_format = true, noexcept = true } }) +add_requires("catch2 v3.4.0") +add_requires("tracy v0.9.1") local imguiUserConfig = path.absolute("src/ImGuiConfig.hpp"); -add_requires("imgui v1.89.6-docking", { configs = { wchar32 = true, freetype = true, user_config = imguiUserConfig } }) +add_requires("imgui v1.89.7-docking", { configs = { wchar32 = true, freetype = true, user_config = imguiUserConfig } }) function CopyDataToDirecotry(targetDir) os.rm(targetDir .. "/data") @@ -69,62 +77,91 @@ function CopyDataToDirecotry(targetDir) os.cp("data/*", targetDir .. "/data") end -package("libsamplerate") - set_kind("library", {headeronly = true}) - set_homepage("http://libsndfile.github.io/libsamplerate/") - set_description("An audio Sample Rate Conversion library") - set_license("BSD-2-Clause") - - add_urls("https://github.com/libsndfile/libsamplerate/archive/$(version).tar.gz", - "https://github.com/libsndfile/libsamplerate.git") +target("imgui-backends") + set_version("1.89.7") + set_kind("static") - add_versions("0.2.2", "16e881487f184250deb4fcb60432d7556ab12cb58caea71ef23960aec6c0405a") + add_includedirs("vendor/imgui-backends/include", {public = true}) - add_deps("cmake") + add_headerfiles("vendor/imgui-backends/include/**.h") + add_files("vendor/imgui-backends/src/**.cpp") - on_install("windows", "linux", "macosx", "iphoneos", "mingw", "android", function (package) - local configs = {} - table.insert(configs, "-DBUILD_PROGRAMS=OFF") - table.insert(configs, "-DBUILD_EXAMPLES=OFF") - table.insert(configs, "-DBUILD_TESTING=OFF") - table.insert(configs, "-DCMAKE_BUILD_TYPE=" .. (package:debug() and "Debug" or "Release")) - table.insert(configs, "-DBUILD_SHARED_LIBS=" .. (package:config("shared") and "ON" or "OFF")) - - import("package.tools.cmake").install(package, configs) - end) -package_end() -add_requires("libsamplerate 0.2.2", { configs = { shared = true } }) + add_packages("imgui", "libsdl") +target_end() target("Glacier1AudioTool") set_version("1.1.0") + set_kind("binary") set_rundir("$(projectdir)") add_defines("IMGUI_USER_CONFIG=\""..imguiUserConfig.."\"") --add_defines("G1AT_BUILD_TESTS") + --add_defines("G1AT_ENABLE_PROFILING") - set_kind("binary") + add_deps("FeldarianBaseLibrary", "imgui-backends", { private = true }) add_files("manifests/**.manifest") - add_headerfiles("src/**.h") + add_includedirs("src") + + add_headerfiles("src/*.h") + --add_files("src/*.c") + add_headerfiles("src/*.hpp") + --add_files("src/*.cpp") + + --add_headerfiles("src/App/**.h") + --add_files("src/App/**.c") + add_headerfiles("src/App/**.hpp") + add_files("src/App/**.cpp") + + --add_headerfiles("src/Config/**.h") + --add_files("src/Config/**.c") + add_headerfiles("src/Config/**.hpp") + --add_files("src/Config/**.cpp") + + --add_headerfiles("src/Core/**.h") + --add_files("src/Core/**.c") + add_headerfiles("src/Core/**.hpp") + add_files("src/Core/**.cpp") - add_headerfiles("src/**.hpp") - add_files("src/**.cpp") + --add_headerfiles("src/G1AT/**.h") + --add_files("src/G1AT/**.c") + add_headerfiles("src/G1AT/**.hpp") + add_files("src/G1AT/**.cpp") + + if (is_plat("windows")) then + --add_headerfiles("src/Platform/Windows/**.h") + --add_files("src/Platform/Windows/**.c") + add_headerfiles("src/Platform/Windows/**.hpp") + add_files("src/Platform/Windows/**.cpp") + elseif (is_plat("linux")) then + --add_headerfiles("src/Platform/Linux/**.h") + --add_files("src/Platform/Linux/**.c") + add_headerfiles("src/Platform/Linux/**.hpp") + add_files("src/Platform/Linux/**.cpp") + elseif (is_plat("macosx")) then + --add_headerfiles("src/Platform/Mac/**.h") + --add_files("src/Platform/Mac/**.c") + add_headerfiles("src/Platform/Mac/**.hpp") + add_files("src/Platform/Mac/**.cpp") + end + set_configvar("G1AT_COMPANY_NAMESPACE", "Feldarian") + set_configvar("G1AT_COMPANY_NAME", "Feldarian Softworks") set_configvar("G1AT_NAME", "Glacier 1 Audio Tool") set_configvar("G1AT_DESCRIPTION", "Tool able to read, write, import and export selected Glacier 1 sound-related formats.") set_configvar("G1AT_HOMEPAGE", "https://github.com/WSSDude/Glacier1AudioTool") - set_configdir("$(buildir)/src/Config") - add_configfiles("src/Config.h.in") - add_includedirs("$(buildir)/src/Config/") - add_headerfiles("$(buildir)/src/Config/**.h") + set_configdir("$(buildir)/generated/Config") + add_configfiles("src/Config/Config.h.in") + add_includedirs("$(buildir)/generated") + add_headerfiles("$(buildir)/generated/Config/**.h") set_pcxxheader("src/Precompiled.hpp") - add_packages("scnlib", "libsdl", "libsndfile", "libsamplerate", "imgui", "xxhash", "toml++") - add_syslinks("comdlg32", "opengl32", "shell32", "icuuc") + add_syslinks("comdlg32", "opengl32", "shell32") + add_packages("scnlib", "libsdl", "imgui", "spdlog", "xxhash", "toml++", "icu4c") before_build(function (target) os.rm(target:targetdir() .. "/data")