From aa77722e9f73de37bd71c66a16e20b812be30550 Mon Sep 17 00:00:00 2001 From: Ilya Shurumov Date: Sun, 18 Dec 2022 23:34:39 +0600 Subject: [PATCH 01/20] - add premake android module --- .../premake_modules/androidndk/LICENSE.txt | 27 + .../premake_modules/androidndk/README.md | 541 +++++ .../premake_modules/androidndk/UNLICENSE.txt | 24 + .../premake_modules/androidndk/_manifest.lua | 11 + .../premake_modules/androidndk/_preload.lua | 110 ++ .../premake_modules/androidndk/androidndk.lua | 465 +++++ .../androidndk/androidndk_project.lua | 1743 +++++++++++++++++ .../androidndk/androidndk_workspace.lua | 513 +++++ 8 files changed, 3434 insertions(+) create mode 100644 src_rebuild/premake_modules/androidndk/LICENSE.txt create mode 100644 src_rebuild/premake_modules/androidndk/README.md create mode 100644 src_rebuild/premake_modules/androidndk/UNLICENSE.txt create mode 100644 src_rebuild/premake_modules/androidndk/_manifest.lua create mode 100644 src_rebuild/premake_modules/androidndk/_preload.lua create mode 100644 src_rebuild/premake_modules/androidndk/androidndk.lua create mode 100644 src_rebuild/premake_modules/androidndk/androidndk_project.lua create mode 100644 src_rebuild/premake_modules/androidndk/androidndk_workspace.lua diff --git a/src_rebuild/premake_modules/androidndk/LICENSE.txt b/src_rebuild/premake_modules/androidndk/LICENSE.txt new file mode 100644 index 00000000..b83a9213 --- /dev/null +++ b/src_rebuild/premake_modules/androidndk/LICENSE.txt @@ -0,0 +1,27 @@ +Copyright (c) 2021 Vitaliy Triang3l Kuzmin. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of premake-androidndk nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 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/src_rebuild/premake_modules/androidndk/README.md b/src_rebuild/premake_modules/androidndk/README.md new file mode 100644 index 00000000..4e018302 --- /dev/null +++ b/src_rebuild/premake_modules/androidndk/README.md @@ -0,0 +1,541 @@ +# premake-androidndk + +A module for generation of ndk-build Android.mk files for [Premake 5](https://premake.github.io/). + +* Providing the same level of **multi-ABI building capabilities** as hand-written Android.mk files, allowing for building for multiple ABIs from one ndk-build invocation and supporting ABI filtering for most of the project settings. +* Supporting all languages accepted by ndk-build — C, C++, the GNU Assembler, Yasm, RenderScript, as well as prebuilt libraries and external Android.mk files. +* Focused on supporting as many Premake project settings as possible, with attention to coverage of edge cases such as allowed characters. +* Preferring exposing Android.mk settings through existing Premake project settings over adding new ones where semantically appropriate to allow porting of projects from other targets with minimal changes. + +Available under the [Unlicense](UNLICENSE.txt), or, similar to Premake, the [BSD 3-Clause “New” or “Revised” License](LICENSE.txt). + +## Usage + +### Generating Android.mk files + +Clone or download the module, and `require("path/to/premake-androidndk/androidndk")` in your workspace's Premake script. Use the `androidndk` action to perform generation. + +All projects — which represent ndk-build modules — in the application must be located in a single workspace, as a workspace corresponds to an Application.mk file and the root Android.mk. + +Add Android platform definitions to the `platforms` of your workspace or the projects in it. This is especially important in two cases — if your workspace targets other operating systems alongside Android, and if you want to specify ABI-specific settings. Using `configurations` for this purpose also works, but generally it's recommended to use the configuration axis for build flavors such as debug/release, while doing all platform and architecture filtering via the platform axis — and due to the nature of specifying platforms and configurations to be built by ndk-build for Android.mk files generated by this module, mixing the two may result in complicated setup and unnecessary duplication of arguments you'll need to pass to ndk-build. + +**Specify the `system` as `"android"`** in your Android platforms and configurations. While this module doesn't check the value of `system` anywhere internally, if it's not specified, Premake will assume that the host OS is the target, which may be undesirable — for instance, build libraries may not have the `"lib"` prefix if the `system` is selected as `"windows"`. + +If you need to specify settings that apply only to certain ABIs, you can specify separate `platforms` (or `configurations`) with different `architecture` values. The supported architectures are `"ARM"` (corresponds to the `armeabi-v7a` ABI), `"ARM64"` (`arm64-v8a` ABI), `"x86"` (`x86` ABI) and `"x86_64"` (`x86_64` ABI). + +For example: + +```lua +configurations({"Debug", "Release") +platforms({"Windows-x86_64", "Android-ARM64", "Android-x86_64"}) +filter({"platforms:Windows-*"}) + system("windows") + systemversion("10.0") +filter({"platforms:Android-*"}) + system("android") + systemversion("24") + cppstl("c++") +filter({"platforms:*-x86_64"}) + architecture("x86_64") +filter({"platforms:*-ARM64"}) + architecture("ARM64") +filter({}) +``` + +It's also possible to specify both architecture-specific and architecture-agnostic (with a nil or `"universal"` architecture) platforms in the same project. In this case, the architecture specialization will be chosen when ndk-build is building for an ABI for which one available, and the architecture-independent settings will be used as a fallback if one is not: + +```lua +platforms({"AndroidOther", "AndroidARMv7", "AndroidARMv8"}) +filter({"platforms:AndroidARMv7"}) + architecture("ARM") +filter({"platforms:AndroidARMv8"}) + architecture("ARM64") +filter({"architecture:ARM or ARM64"}) + files({"neonmath.cpp"}) +filter({}) +-- `armeabi-v7a` ABI will use the AndroidARMv7 platform with neonmath.cpp. +-- `arm64-v8a` ABI will use the AndroidARMv8 platform with neonmath.cpp. +-- `x86` and `x86_64` ABIs will use the AndroidOther platform without neonmath.cpp. +``` + +Note that deprecated ABIs such as `armeabi`, `armeabi-v7a-hard`, `mips`, `mips64` are not supported. `armeabi-v7a` builds by default will have NEON enabled and will use the Thumb instruction set for release configurations, this can be changed via settings listed in the section below. + +It is important to consider that **Premake settings such as `architecture` are assigned to configuration–platform pairs**. So, if you want to use `filter({"architecture:"})`, you **must create a platform or a configuration for that architecture**, otherwise it will not work. + +To exclude a project from building for certain ABIs, you can set its `kind` to `None` with the required filter. + +Most settings allow GNU make variable expansion and function call passthrough, so you can use environment variables, or variables and functions provided by ndk-build like `$(TARGET_ARCH_ABI)`, in your projects, and they will be expanded at build time. You need to be careful not to reference variables or functions that may result in disallowed characters in the specific context, such as whitespaces in settings that end up being written to a list variable, however — it's not possible for the module to validate the value in this case. To use the dollar sign as a character, specify `$$` instead. Paths starting with a dollar sign (even if it's `$$` denoting an escaped raw `$` character) are treated as absolute by Premake, allowing for the usage of paths relative to directories such as `$(NDK_ROOT)`. If you want to override this behavior, explicitly prefix the path with `./`. + +#### Usage of prebuilt libraries and external Android.mk files + +Normally, this module provides functionality for building of projects from source code. + +However, it also exposes the prebuilt library functionality of ndk-build. This is the recommended way of including non-system library binaries in the workspace and linking projects against them, as it lets ndk-build properly ensure that the library is copied into the destination directory properly and that it's loaded from the correct path. ndk-build will generate warnings if the project is linked against non-system libraries via system `links` or via `linkoptions`. + +In addition, it's also possible to create a project that will use an external Android.mk file instead of its own settings (certain settings still must be correctly specified for linkage purposes, however). + +To create a project using a prebuilt library or an external Android.mk file, specify **just one `.a`, `.so` or `.mk` file** and **no other source files** in the `files` setting for the desired configurations/platforms. Also, you **must specify the correct `kind`** of the project — `"SharedLib"` for `.so`, `"StaticLib"` for `.a`, or the kind that matches the actual build script included in the external Android.mk. + +Projects using an external Android.mk files have special rules regarding their usage, specifically: + +- The external Android.mk must contain settings for only at most one project (module). +- The `kind` of the project must match the build script used in the external Android.mk — `"SharedLib"` for `BUILD_SHARED_LIBRARY` or `PREBUILT_SHARED_LIBRARY`, `"StaticLib"` for `BUILD_STATIC_LIBRARY` or `PREBUILT_STATIC_LIBRARY`, `"ConsoleApp"` for `BUILD_EXECUTABLE`. **Do not use the `"Makefile"` kind** — it has a completely different purpose, and is not supported by this module. The module must know the actual `kind` for linkage. +- The name of the project must be the same as `LOCAL_MODULE` in the external Android.mk. + +The following settings have effect when used in a prebuilt library project or an external Android.mk project: + +- `configurations` +- `flags` + - `"ExcludeFromBuild"` + - `"LinkTimeOptimization"` (for static libraries, if any object files in it are built with `-flto`) +- `linkoptions` (the only supported options are `-u` or `-Wl,--undefined` exported from static libraries) +- `links` (must match `LOCAL_SHARED_LIBRARIES` and `LOCAL_STATIC_LIBRARIES`/`LOCAL_WHOLE_STATIC_LIBRARIES` for external Android.mk projects referencing other Premake projects, external or not; also, for static libraries, must include the system libraries from `LOCAL_EXPORT_LDLIBS`) +- `location` (or `basedir` if not provided) +- `kind` +- `platforms` +- `project` (must match `LOCAL_MODULE` in the external Android.mk) +- `wholelib` + +For example, to add the Android Native App Glue to your workspace, you can create a project with the following settings: + +```lua +project("android_native_app_glue") + kind("StaticLib") + files({"$(NDK_ROOT)/sources/android/native_app_glue/Android.mk"}) + links({"log", "android"}) + linkoptions({"-u ANativeActivity_onCreate"}) +``` + +#### RenderScript library linkage + +To link projects with RenderScript sources, you may need to add some of these prebuilt library projects to your workspace (most importantly `"RScpp_static"`) and to specify them in `links` of the projects that use RenderScript: + +```lua +project("RSSupport") + kind("SharedLib") + files({"$(RENDERSCRIPT_TOOLCHAIN_PREBUILT_ROOT)/platform/$(TARGET_ARCH)/libRSSupport.so"}) +project("RSSupportIO") + kind("SharedLib") + files({"$(RENDERSCRIPT_TOOLCHAIN_PREBUILT_ROOT)/platform/$(TARGET_ARCH)/libRSSupportIO.so"}) +project("blasV8") + kind("SharedLib") + files({"$(RENDERSCRIPT_TOOLCHAIN_PREBUILT_ROOT)/platform/$(TARGET_ARCH)/libblasV8.so"}) +project("RScpp_static") + kind("StaticLib") + files({"$(RENDERSCRIPT_TOOLCHAIN_PREBUILT_ROOT)/platform/$(TARGET_ARCH)/libRScpp_static.a"}) +``` + +### Invoking ndk-build + +#### Setting up applicaton settings + +The basic setup is different depending on whether you're using the `externalNativeBuild` functionality of Gradle to build the application. + +The module generates an Application.mk file containing basic settings for the entire application, with some support for Premake configuration and platform filtering that may be useful, for instance, for choosing `APP_DEBUG` and `APP_OPTIM` based on the selected configuration. However, as ABI filtering is not available in Application.mk, it will be more coarse than for settings that go to Android.mk — it is assumed that all Application.mk-level settings should not depend on the target ABI, you can see the exact list of the settings that go to Application.mk in the list of supported project settings. + +If you're launching ndk-build as a custom task, or not using Gradle at all, you need to specify the path to the Application.mk in the ndk-build command arguments, as `NDK_APPLICATION_MK:=path/to/WORKSPACE_NAME.Application.mk`, where `WORKSPACE_NAME` is the name of the Premake workspace for the application. The Application.mk file is written to the `location` directory of the workspace. + +**Gradle's `externalNativeBuild`, however, causes most Application.mk settings to be ignored and overridden by the settings specified in the Gradle script itself.** Because of this, using the Application.mk file generated by this module may not be absolutely necessary, but for correctness, you should still set the `NDK_APPLICATION_MK` variable in ndk-build arguments, otherwise it will try to use the Application.mk from the default path — it's better to express the intentions explicitly than to rely on the file not currently existing. However, you'll need to specify the correct settings in the Gradle script manually anyway. Because Gradle scripts contain settings not only for NDK, but also for all aspects of the application, and since the layout of configurations — build types and product flavors — may vary greatly between applications, Gradle setup is out of the scope of this module. + +Here is an example of configuring the application settings relevant to the usage of files generated by this module: + +```groovy +android { + // The Android NDK version to build the application with. + // If omitted, the latest installed version will be used. + ndkVersion '23.0.7599858' + + // Per-configuration Gradle settings. + // May be specified for defaultConfig, as well as for buildTypes and productFlavors. + defaultConfig { + // Minimum Android SDK version supported by the application. + // Corresponds to APP_PLATFORM := android- in Application.mk (Premake `systemversion`). + minSdkVersion 14 + + externalNativeBuild { + ndkBuild { + // See com.android.build.api.dsl.ExternalNativeNdkBuildOptions documentation. + + // Application.mk path - specifying the correct one is recommended. + arguments 'NDK_APPLICATION_MK:=path/to/WORKSPACE_NAME.Application.mk', + // Premake platforms to build for - see the section about configuration and platform selection below. + 'PREMAKE_ANDROIDNDK_PLATFORMS:=Android-ARM', + 'PREMAKE_ANDROIDNDK_PLATFORMS+=Android-ARM64' + } + } + + ndk { + // See com.android.build.api.dsl.Ndk documentation for more useful options such as `jobs`. + + // The list of the ABIs to build this application for. + // Corresponds to APP_ABI in Application.mk. + // Should match the actual list of ABIs supported by at least some of the projects in the workspace. + // If omitted, ndk-build will try to build for all ABIs supported by the used NDK version. + // In this case, you should provide an architecture-agnostic platform/configuration for the projects. + // It may be fine not to specify this if you target only a subset of APIs, but ndk-build will be emitting warnings. + abiFilters 'armeabi-v7a', 'arm64-v8a' + + // The C++ STL to use. + // Corresponds to APP_STL in Application.mk. + // If omitted, APP_STL (Premake `cppstl` and `staticruntime`) from the Application.mk will be used. + // If that's not specified too, the default STL for the current API version will be selected. + stl 'c++_static' + } + } + + buildTypes { + release { + debuggable false + + externalNativeBuild { + ndkBuild { + // Premake configurations to build for - see the section about configuration and platform selection below. + arguments 'PREMAKE_ANDROIDNDK_CONFIGURATIONS:=Release' + } + } + } + + debug { + debuggable true + + externalNativeBuild { + ndkBuild { + // Premake configurations to build for - see the section about configuration and platform selection below. + arguments 'PREMAKE_ANDROIDNDK_CONFIGURATIONS:=Debug' + } + } + } + } + + externalNativeBuild { + ndkBuild { + // See com.android.build.api.dsl.NdkBuild documentation. + // This is required to initiate native code building at all. + + // The Android.mk file to use - the generated workspace Android.mk in the `location` of the workspace. + // Corresponds to APP_BUILD_SCRIPT in Application.mk. + path file('path/to/WORKSPACE_NAME.wks.Android.mk') + } + } +} +``` + +#### Specifying Premake configurations and platforms to build + +Because a single ndk-build invocation builds for multiple ABIs, the usage of the generated files is slightly unusual compared to most build systems targeted by Premake where only a single configuration and platform pair is selected for building. + +Instead of letting you select just one configuration and platform, this module allows you to execute ndk-build for **multiple platforms and configurations**. + +For this purpose, the module provides two variables that you need to set in the arguments of the ndk-build invocation (`externalNativeBuild.ndkBuild.arguments` for a Gradle build configuration): + +* `PREMAKE_ANDROIDNDK_CONFIGURATIONS` — Premake configurations to build, **at least one must be specified**. +* `PREMAKE_ANDROIDNDK_PLATFORMS` — Premake platforms to build for. Optional, if none are specified, will be building for all platforms specified in any project. + +To set a variable to just one value, you can use the `VARIABLE:=value` syntax of the ndk-build argument. For multiple values, you need to provide each in a separate argument as `VARIABLE+=value` (preferably the first with `:=` still to ensure it's overwritten if there's an environment variable with the same name). The Gradle example above shows how you can enable building for multiple platforms representing different ABIs, and for a configuration depending on the Gradle build type. + +This, however, does not mean that you can create debug and release builds at once — rather, this architecture is designed specifically to provide a way for building for multiple ABIs as usual while being able to use an `architecture` filter in Premake. Because of this, **you must ensure** that **for every ABI, only at most one configuration–platform pair will be selected** for every project. An ambiguous selection of platforms and configurations will result in an undefined behavior. + +Platform-agnostic projects — those that have no `platforms` inherited from the workspace or defined — will be built regardless of the value of `PREMAKE_ANDROIDNDK_PLATFORMS` (only configuration selection will be used for them). + +## Supported settings + +Please carefully verify that the settings you're using in your projects are handled in a way that's supported by this module and by ndk-build itself. Most importantly, please **check the settings that are listed as per-file or per-extension here**, especially if you have source files of different languages in your projects. + +### Per-file or per-configuration/per-platform for a project, ABI-filtered + +There is a small number of settings for which it's possible to specify the value for individual source files using the `files` filter. + +- **`armisa`** (new) = `"A32"` / `"T32"` (default) + - ARMv7 instruction set to use. By default, Thumb (`"T32"`) will be used for release builds. Debug builds, however, always use A32. + - At the project configuration scope, it controls `LOCAL_ARM_MODE`. + - At the file scope, it can be used to build the specified files for A32 in a Thumb project, **but not vice versa**, by adding the `.arm` suffix to the file in `LOCAL_SRC_FILES`. Alternatively, you can use the `.arm` suffix (if needed, as a part of `.arm.neon`, but not `.neon.arm`) directly in the `files` setting, which will take precedence. +- **`flags`** + - `ExcludeFromBuild` + - Also supported for excluding entire projects on specified configurations/platforms. +- **`vectorextensions`** (for the `"ARM"` architecture) = `"ARMv7"` (new) / `"NEON"` (default, new) + - Whether to allow the compiler to generate instructions from the NEON SIMD instruction set as part of its optimizations. Specifying `"ARMv7"` (analogous to `"IA32"` on x86) disables NEON, specifying `"NEON"` enables it. By default, for consistency with NDK versions starting with r21, NEON will be enabled, even if the project doesn't explicitly specify `vectorextensions` (so on pre-r21, NEON will be used for Premake projects too). + - At the project configuration scope, it controls `LOCAL_ARM_NEON`. + - At the file scope, it can be used to build the specified files with NEON code generation in a project with NEON disabled, **but not vice versa**, by adding the `.neon` suffix to the file in `LOCAL_SRC_FILES`. Alternatively, you can use the `.neon` suffix (if needed, as a part of `.arm.neon`, but not `.neon.arm`) directly in the `files` setting, which will take precedence. + - For the allowed values on other architectures, see the per-configuration/per-platform settings section. + +### Per-language or per-configuration/per-platform for a project, ABI-filtered + +While ndk-build doesn't provide a way to specify compiler flags and most other settings for individual source files, it supports multiple source languages with different compilers, which accept different build options. Premake, however, exposes most build settings under language-agnostic names. + +To specify which compiler should receive the needed value, you can use file extension filters. + +Because the module supports `.arm`, `.neon` and `.arm.neon` suffixes, as well as many C++ extensions, it's not recommended to list file extensions manually. Instead, built-in filter constants provided by the module should be preferred, as they include the ARM suffixes and all the supported extensions. + +For including a specific language, the following variables are available (note that they must be used directly, and if needed, via `..` concatenation — **`%{}` string interpolation will not locate them**): + +- `premake.modules.androidndk.filefilters.as` for the GNU Assembler (GAS) +- `premake.modules.androidndk.filefilters.asm` for Yasm +- `premake.modules.androidndk.filefilters.c` for C +- `premake.modules.androidndk.filefilters.cpp` for C++ +- `premake.modules.androidndk.filefilters.rs` for RenderScript + +Each of those filters is a single string which already has the `"files:"` prefix (for instance, `premake.modules.androidndk.filefilters.c` is `"files:**.c or files:**.c.arm or files:**.c.neon or files:**.c.arm.neon"`). + +To exclude a language from a file filter, `filefilters` also includes filters prefixed with `not`, such as `premake.modules.androidndk.filefilters.notc`. Unlike the inclusive filters, the exclusive are tables, because Premake exposes the logical `and` as separate table elements. `premake.modules.androidndk.filefilters.notc` is `{ "files:not **.c", "files:not **.c.arm", "files:not **.c.neon", "files:not **.c.arm.neon" }`, for example. Premake filter tables can be nested, you don't need to perform flattening manually if you want to combine the language filters with additional terms. + +In addition, raw combinations of extensions and ARM suffixes are available in `filefilters` with the `extensions` suffix, such as `premake.modules.androidndk.filefilters.cextensions`, which is `{ ".c", ".c.arm", ".c.neon", ".c.arm.neon" }` (without the `**` recursive wildcard). You can do your own processing of them using functions like `table.translate` and `table.concat`, for instance, to attach all the possible extensions to a specific file name. + +Note that ndk-build treats the uppercase `.C` extension as C++. To avoid imposing additional constraints, this module allows using the `.C` extension for C++, even though other Premake actions may treat it as C, especially considering that `path.hasextension` in Premake is case-insensitive. However, **Premake filters are case-insensitive, and `"files:**.c"` or `"files:**.C"` will match *both* C `.c` and C++ `.C` sources**, leading to the specified settings being used for both C and C++. Therefore, **it's recommended to completely avoid using the uppercase `.C` extension**. The `.C` extension is also not included in the `premake.modules.androidndk.filefilters` constants for this reason. + +It is important that **you must not try to derive a `language` filter from an extension filter** because the `language` setting has a `"project"` scope in Premake rather than `"config"`, and thus it doesn't support file-specific or even configuration- or platform-specific overrides, in addition to not having allowed values for GAS, Yasm and RenderScript, so **the following will not work**: + +```lua +filter(premake.modules.androidndk.cfilefilter) + language("C") -- This WILL NOT WORK! +filter(premake.modules.androidndk.cppfilefilter) + language("C++") -- This WILL NOT WORK! +filter("language:C") + defines({"MY_NULL=((void *)0)"}) +filter("language:C++") + defines({"MY_NULL=0"}) +``` + +In addition, if the `NoPCH` flag is not enabled in the project for the configuration–platform pair, and the file specified in `pchheader` is also listed in `files`, any file-filtered settings for it will be treated as C++ settings. + +With some exceptions, most language-specific settings can be set independently for each language supported by this module. + +- **`buildoptions`** (C, C++, GAS, Yasm, RenderScript) + - One build option may contain one or multiple compiler arguments separated with whitespaces. + - Double quotation marks (`"`) may be used to specify a single compiler argument containing whitespaces. + - If double quotation marks need to be escaped, they need to be prefixed with `\`, as `"\\\""` according to Lua string literal escaping rules. + - The backslash character (`\`) itself also needs to be escaped with another `\`, as `"\\\\"`, so the module can distinguish between a backslash used for escaping the double quote character and an actual backslash character. + - All other characters after GNU make `$` variable or function reference expansion are allowed, and other shell-interpreted characters will be escaped automatically at build time. + - Because of the way the values are gathered from the used filters, duplicate `buildoptions` are eliminated. For this reason, always specify multiple-argument options as `{ "-prefix value1", "-prefix value2" }`, not `{ "-prefix", "value1", "-prefix", "value2" }` (as the latter will become `"-prefix value1 value2"`). + - See the documentation for the `"LinkTimeOptimization"` flag here for details about the handling of `"-flto=…"`. +- **`cdialect`** (C) +- **`cppdialect`** (C++) +- **`flags`** + - `"FatalCompileWarnings"` (C, C++, Yasm) + - `"NoBufferSecurityCheck"` (C, C++) + - `"ShadowedVariables"` (C, C++) + - `"UndefinedIdentifiers"` (C, C++) +- **`defines`** (C, C++, Yasm) + - All `defines` are passed to the compiler before `undefines` even if they're specified both within and without an extension filter. +- **`disablewarnings`** (C, C++, Yasm) +- **`enablewarnings`** (C, C++, Yasm) +- **`fatalwarnings`** (C, C++, Yasm) + - For Yasm, this is treated as `enablewarnings`. +- **`floatingpoint`** (C, C++) + - `"Strict"` is treated as `"Default"`. +- **`floatingpointexceptions`** (C, C++) +- **`forceincludes`** (C, C++, Yasm) + - For C and C++, double quotation mark characters (`"`) are disallowed, as they would terminate the `#include "path"` statement inserted by the compiler. + - For Yasm, `"`, `'`, `;` characters are disallowed. +- **`includedirs`** (**C, C++, GAS and Yasm *combined***, RenderScript separately) + - C, C++, GAS and Yasm use **the same** list of include directories (that is written to `LOCAL_C_INCLUDES`). + - All `includedirs` are passed to the compiler before `sysincludedirs`. + - Whitespaces and `#`, `$` (after GNU make reference expansion) characters are disallowed. +- **`inlinesvisibility`** (C, C++) + - Unlike in other Premake actions using `premake.clang` or `premake.gcc`, this is also supported for C, not only C++. +- **`omitframepointer`** (C, C++) + - To use the Address Sanitizer, this needs to be set to `Off` — see the [Address Sanitizer](https://developer.android.com/ndk/guides/asan) guide on Android Developers. +- **`strictaliasing`** (C, C++) +- **`sysincludedirs`** (**C, C++, GAS and Yasm *combined***, RenderScript separately) + - See `includedirs`. +- **`undefines`** (C, C++, Yasm) + - All `defines` are passed to the compiler before `undefines` even if they're specified both within and without an extension filter. +- **`unsignedchar`** (C, C++) +- **`visibility`** (C, C++) + - Unlike in other Premake actions using `premake.clang` or `premake.gcc`, this is also supported for C, not only C++. +- **`warnings`** (C, C++, Yasm) + - For Yasm, only `"Off"` has effect — other values are treated as warnings enabled as normal. + +### Per-configuration/per-platform for a project, ABI-filtered + +- **`architecture`** + - If an architecture is specified, the settings for this configuration–platform pair will be used will be used while building for the respective ABI if the configuration and the platform are selected for building via `PREMAKE_ANDROIDNDK_CONFIGURATIONS` and `PREMAKE_ANDROIDNDK_PLATFORMS`. In this case, the `architecture` filter may be used to provide ABI-specific settings. + - `"ARM"` for the `armeabi-v7a` ABI. + - `"ARM64"` for the `arm64-v8a` ABI. + - `"x86"` for the `x86` ABI. + - `"x86_64"` for the `x86_64` ABI. + - Leave unspecified or set to `"universal"` to provide fallback settings that will be used for the project for ABIs without a specialization. + - Generally `architecture` should be specified under a `platforms` filter, or, depending on your configuration structure, under a `configurations` one. See the “Usage” section for more information ABI filtering of settings. +- **`exceptionhandling`** = `"Off"` / `"On"` (default) +- **`files`** + - For a built Premake project: + - The following languages are supported: + - C (`.c`) + - C++ (`.cc`, `.cp`, `.cxx`, `.cpp`, `.CPP`, `.c++`, `.C`) + - The list of allowed extensions is broader than the default for Premake v5.0.0-alpha16, but matches the default for the NDK r23). + - Note that while ndk-build (and therefore this setting) is case-sensitive, Premake filters are not. Therefore, a `files:**.c` or a `files:**.C` filter will cause both C `.c` and C++ `.C` to pass, and extension-filtered language-specific settings such as `buildoptions` intended only for C++ will be used for C as well if both are present in the project, for example — see the section about per-language settings. It's better to avoid using the `.C` extension completely. + - GNU Assembler (`.s`, `.S`) + - Yasm (`.asm`) + - `"x86"` and `"x86_64"` architectures only — will be ignored automatically while building for other ABIs, including in architecture-agnostic projects. + - RenderScript (`.rs`, `.fs`) + - `.arm`, `.neon` and `.arm.neon` (but not `.neon.arm`) suffixes are allowed — see the documentation for per-file `armisa` and `vectorextensions` settings, which can be used as an alternative (using file-filtered `armisa` and `vectorextensions` is recommended instead so filters like `"files:**.c"` can still be used rather than `"files:**.c or **.c.arm or **.c.neon or **.c.arm.neon"`, however — though for extension filtering, constants like `premake.modules.androidndk.filefilters.c` are recommended, which include the `.arm` and `.neon` suffixes). + - Whitespaces, backtick, and `"`, `#`, `$` (after GNU make reference expansion), `&`, `'`, `(`, `)`, `,`, `;`, `<`, `>`, `|` characters are disallowed. The backslash is allowed as a path separator on Windows, but disallowed on Linux. + - To create a prebuilt library project or to use an external Android.mk file, specify **only one** `.so` (for the `"SharedLib"` kind), `.a` (for the `"StaticLib"` kind) or `.mk` file, and **no other source files**. See the “Usage” section for more information about the required and supported settings for prebuilt and external projects. + - In prebuilt library paths, whitespaces, and `"`, `#`, `$` (after GNU make reference expansion), `%`, `&`, `*`, `;`, `<`, `>`, `?`, `|` characters are disallowed on Windows. On other operating systems, backtick, `'`, `(`, `)`, `\` characters are not supported. + - In external Android.mk paths, whitespaces are not disallowed. + - All irrelevant file types (such as headers) will be ignored automatically. +- **`flags`** + - `"ExcludeFromBuild"` + - Also supported for excluding individual source files from building. + - `"FatalLinkWarnings"` + - For shared libraries and executables only. + - Unlike in ndk-build itself, fatal link warnings are disabled by default (`LOCAL_DISABLE_FATAL_LINKER_WARNINGS := true`). + - `"LinkTimeOptimization"` + - If used in a static library, shared libraries and executables linked against it will also be linked with link-time optimization (the transitivity ensured for this options, however, doesn't apply to building of source files). + - It's possible to override the default link-time optimization type by specifying the desired link-time optimizations type, such as `-flto=thin`, in **both** `buildoptions` and `linkoptions`. The specific `-flto=` type will also be propagated from `linkoptions` of static library dependencies (though in this case, all linked static libraries must have the same LTO type, and static library dependency analysis only checks `linkoptions`, not `buildoptions`). + - `"NoPCH"` + - Causes `pchheader` to be ignored — see `pchheader` for more information. +- **`formatstringchecks`** (new) = `"Off"` / `"On"` (default) + - Corresponds to `LOCAL_DISABLE_FORMAT_STRING_CHECKS` (but enabling instead of disabling), whether to check `printf` format strings in the sources. +- **`isaextensions`** + - This should be used only in libraries with code used conditionally based on the information provided by `cpuid`, or for emulation purposes, otherwise it may prevent the app from working on physical devices. + - All `"x86"` and `"x86_64"` architecture `isaextensions` normally supported by Premake actions targeting Clang are supported. +- **`libdirs`** + - Search paths for library binaries specific directly via `links`. + - Not recommended as using library binaries directly via linker arguments is discouraged by ndk-build — prefer using prebuilt library projects, and see `links` for more information. + - All `libdirs` gathered from the project and its static library dependencies are passed to the linker before `syslibdirs`. +- **`linkoptions`** + - Most options are supported only in shared libraries and executables, but there are some exceptions which are exported from static libraries as well. + - See `buildoptions` for information about passing multiple arguments, characters that need to be escaped manually, deduplication, disallowed characters. + - Going to Clang++ rather than directly to LLD — `-Wl` may be needed for many options. + - Unlike in other Premake actions, some parsing is done: + - Options prefixed with `-l`, `-L` (with or without `-Wl`), `-Wl,--library`, `-Wl,--library-path` will go to `LOCAL_LDLIBS` instead of `LOCAL_LDFLAGS`, and will be exported from static libraries to dependent shared libraries, similarly to `links`. This may be useful if you have a project named the same as a system library, but you want to link against that system library (for instance, `-llog` if there is a project named `"log"`). See `links` and `libdirs` for more information. + - Options prefixed with `-u` (with or without `-Wl`) or `-Wl,--undefined` will also be exported from static libraries transitively to allow preserving “unused” symbols imported from static libraries in the dependent shared libraries, primarily JNI native function implementations in static libraries — similar to `wholelib`, but more granular, for individual symbols. + - See the documentation for the `"LinkTimeOptimization"` flag here for details about the handling of `"-flto=…"`. +- **`links`** + - Premake projects and system libraries to link against — usable in all kinds of projects (in shared libraries and executables, as well as in static libraries for transitive linkage). + - If a shared library or an executable is linked against a static library project, it will automatically be linked against all system libraries referenced by its static library dependencies, even if static library dependencies are chained via `links`. Transitivity across shared libraries is not provided, however, as it's not necessary and may be undesirable — instead of using `LOCAL_EXPORT_LDLIBS`, the module traverses the dependency tree by itself. This is done for consistency with other Premake actions such as Visual Studio. + - See `wholelib` and `wholelibs` for information about importing static libraries as whole archives. + - If you have a project named the same as a system library, but you still want to link against the system library, you can use a `buildoptions` entry with the `-l` prefix (for instance, `-llog` if there is a project named `"log"`). + - Generally shouldn't be used for anything but linking to other projects and to the NDK system libraries — ndk-build will generate warnings for non-system libraries. Prebuilt library projects (see the “Usage” section) should be preferred for linking against non-system library binaries directly. However, the module still provides the functionality for linking against arbitrary library files: + - Full paths, `libdirs` and `syslibdirs` can be used for specifying search paths (however, there's no way to link against two libraries with the same name under different paths). + - Both short library names and full file names are allowed. If the file name ends with `.a` or `.so`, it's treated as a full name — the `"lib"` prefix must be explicitly specified if needed. + - The `":"` prefix can be added to the file name explicitly to force handling of it as a full file name. +- **`kind`** + - `"SharedLib"` or `"StaticLib"` for a built or a prebuilt shared or static library. + - `"ConsoleApp"` for an executable. + - `"None"` to exclude the project from building for the current configuration/platform. + - Note that `"Makefile"` is not a supported option — an external Android.mk file must be used through `files`, and the project for it must have the `kind` that matches the actual ndk-build script included by it. + - For more information about the usage of prebuilt libraries and external Android.mk files, see the section about them in “Usage”. +- **`renderscriptcompatibility`** (new) = `"Off"` (default) / `"On"` + - Corresponds to `LOCAL_RENDERSCRIPT_COMPATIBILITY`. +- **`renderscriptincludedirsoverride`** (new) = `"Off"` (default) / `"On"` + - Corresponds to the usage of `LOCAL_RENDERSCRIPT_INCLUDES_OVERRIDE` instead of `LOCAL_RENDERSCRIPT_INCLUDES`, whether to ignore the NDK built-in platform and toolchain RenderScript include search paths. +- **`pchheader`** + - Suffixes such as `.arm` and `.neon` are not supported — handling of ARMv7 ISA overrides is performed internally in ndk-build. + - Whitespaces, backtick, and `"`, `#`, `$` (after GNU make reference expansion), `&`, `'`, `(`, `)`, `,`, `;`, `<`, `=`, `>`, `|` characters are disallowed (same as in `files` for sources, but additionally `=`). The backslash is allowed as a path separator on Windows, but disallowed on Linux. + - ndk-build treats the precompiled header as C++ code. The module will configure variables necessary for building C++ code (such as `LOCAL_CPPFLAGS`) if the precompiled header is present, however, if you have any C++-specific settings with a file extension filter, you need to provide at least one source file with the respective extension, otherwise this module will not be able to access those settings. If the file specified in `pchheader` is listed among `files`, any file-filtered settings applied to it will also be treated as C++ settings. + - Ignored if the `"NoPCH"` flag is enabled for the project configuration/platform. +- **`rtti`** = `"Off"` / `"On"` (default) +- **`targetprefix`**, **`targetname`**, **`targetsuffix`** + - Combined into `LOCAL_MODULE_FILENAME`. + - Overriding the binary path or extension is not supported. + - Whitespaces and `#`, `$` (after GNU make reference expansion), `%`, `/`, `;`, `|` characters are disallowed. + - Only removing the `lib` prefix works when invoking ndk-build from Gradle as of Gradle 7.0.2 because it gathers the names of the targets to build from `LOCAL_MODULE_FILENAME` instead of `LOCAL_MODULE`. If executing ndk-build manually without a list of targets, or with a correctly specified list of them, other values are supported. +- **`undefinedsymbols`** (new) = `"Off"` (default) / `"On"` + - For shared libraries and executables only. + - Corresponds to `LOCAL_ALLOW_UNDEFINED_SYMBOLS`, if enabled, errors will not be thrown for undefined symbols, instead, the symbols will be resolved at runtime. +- **`shortcommands`** (new) = `"Off"` (default) / `"On"` + - Corresponds to `LOCAL_SHORT_COMMANDS`, whether to execute build commands from a file rather than directly via the shell, as if the command line is too long, it may not fit in the 8191 character limit on Windows. +- **`syslibdirs`** + - See `libdirs`. +- **`system`** + - Must be `"android"` for the correct library name prefix (`"lib"`). +- **`thinarchive`** (new) = `"Off"` (default) / `"On"` + - For static libraries only. + - Corresponds to `LOCAL_THIN_ARCHIVE`, whether to store only object file paths instead of the object themselves in the static library being built. +- **`vectorextensions`** (for the `"x86"` and `"x86_64"` architectures) + - This should be used only in libraries with code used conditionally based on the information provided by `cpuid`, or for emulation purposes, otherwise it may prevent the app from working on physical devices. + - Allowed values on the `"x86"` architecture: `"SSE4.1"`, `"SSE4.2"` (new), `"AVX"`, `"AVX2"` (SSSE3 and below are required by Android and are always supported). + - Allowed values on the `"x86_64"` architecture: `"AVX"`, `"AVX2"` (SSE4.2 and below are required by Android and are always supported). + - For the allowed values on the `"ARM"` architecture, see the per-file settings section. +- **`wholelib`** (new) = `"Off"` (default) / `"On"` + - For static libraries only. + - Whether all object files from this static library should be included in the shared libraries (but not executables) referencing it (and this library will be added to `LOCAL_WHOLE_STATIC_LIBRARIES` instead of `LOCAL_STATIC_LIBRARIES`). This is useful, for instance, when exporting JNI native function implementations from a static library. + - This setting is for **exporting** the requirement that the static library must be linked as a whole archive — for the equivalent for importing, see `wholelibs` (a static library will be linked via `LOCAL_WHOLE_STATIC_LIBRARIES` rather than `LOCAL_STATIC_LIBRARIES` if it enables `wholelib` for itself, or if it's specified in `wholelibs` of the project importing it — you only need either to specify `wholelib` in the dependency or to add it to `wholelibs` of the dependent projects; though specifying both the same time is fine, that's redundant). +- **`wholelibs`** (new) + - List of static library project names among the `links` of the project to link as whole archives. + - For more information about whole static libraries, see `wholelib` — this setting provides the same functionality, but for **importing** static library dependencies as whole archives (only one of `wholelib` or `wholelibs` is enough). + - If a project is listed in `wholelibs`, it still needs to be added to `links` to be linked — this setting is merely a modifier, and therefore it's fine to just list all static library projects that need to be linked as whole archives once for the entire workspace (though `wholelib` is more suited for this purpose). + +### Per-configuration/per-platform for a workspace, not ABI-filtered + +These settings have effect on `APP` variables in the Application.mk rather than `LOCAL` variables in projects Android.mk files. + +There is a single Application.mk file for the entire workspace, and the same values of the `APP` variables are used regardless of the current target ABI. Thus, **for all configurations and platforms selected in `PREMAKE_ANDROIDNDK_CONFIGURATIONS` and `PREMAKE_ANDROIDNDK_PLATFORMS`, the values of these settings must be the same for**: + +- All projects in the workspace; +- All target ABIs (`architecture`s). + +For all selected configurations (which are visited in an undefined order), the module tries to locate the value in: + +1. The workspace itself. +2. The `startproject`. +3. For all selected platforms, visited in an undefined order, platform-specific projects, also in an undefined order. +4. Platform-agnostic projects, in an undefined order. + +You can use, for instance, `optimize("Off")` in the `"Debug"` configuration, and `optimize("On")` in the `"Release"` one, as long as you build the workspace with **either** `PREMAKE_ANDROIDNDK_CONFIGURATIONS:=Debug` or `PREMAKE_ANDROIDNDK_CONFIGURATIONS:=Release`, but not both at once. However, you can't disable optimizations for specific projects in the `"Release"` configuration in this case. + +- **`cppstl`** (new) = `"Default"` / `"c++"` / `"none"` / `"system"` + - The C++ standard library to use. + - NDK versions before r18 also support `"gabi++"`, `"gnustl"`, `"stlport"`. + - Use `staticruntime` to specify whether to link against the static standard library or against the shared one. +- **`optimize`** + - Handled in a way that approximates the behavior of other Premake actions. + - Unspecified, `"Off"`, `"Debug"` result in `APP_OPTIM := debug`. + - Anything else (`"Size"`, `"Speed"`, `"Full"`) results in `APP_OPTIM := release`, and also force-disables `APP_DEBUG`. +- **`symbols`** + - Handled in a way that approximates the behavior of other Premake actions. + - Ignored if `optimize` is set to a value that results in optimization enabled. + - Unspecified, `"Off"`, `"Default"` result in `APP_DEBUG := true`. + - Anything else (`"On"`, `"FastLink"`, `"Full"`) results in `APP_DEBUG := false`. +- **`staticruntime`** = `"Default"` / `"Off"` / `"On"` (default) + - Whether to use the static C++ standard library (`cppstl`) as opposed to a shared one. + - Static by default, consistent with the default CMake behavior (where `c++_static` is the default standard library). + - Ignored for `"none"` and `"system"` standard libraries. +- **`systemversion`** + - Minimum Android SDK version required by the application, as a string representation of a number (corresponds to `APP_PLATFORM := android-systemversion`). + +### Per-project or per-workspace + +- **`basedir`** +- **`configurations`** + - Whitespaces and `%`, `(`, `)`, `,` characters are disallowed (configuration and platform names are used in GNU make list function calls). +- **`location`** + - The directory where the Android.mk file for the project or the Application.mk and the root Android.mk for the workspace will be placed (if provided — otherwise `basedir` will be used). + - For projects, it is heavily recommended to set this to a folder that doesn't contain header files. This is the path that will be used as `LOCAL_PATH`, and ndk-build internally adds `LOCAL_PATH` as the last include directory, causing `LOCAL_PATH` to be treated as a more “system” include search path than the system paths themselves. This causes issues when the `LOCAL_PATH` directory contains header files named the same as C and C++ standard library headers — the LLVM libc++ uses `#include_next` in a few files (such as `math.h`), causing project's files to included from system headers; this is especially dangerous if the local `"math.h"` itself `#include`s ``. +- **`platforms`** + - See `configurations`. +- **`project`** + - Whitespaces and `#`, `$`, `%`, `/`, `:`, `;`, `=`, `|` characters are disallowed. + - GNU make variable or function references (`$`) are disallowed. +- **`startproject`** + - The start project will have a higher priority when locating setting values for Application.mk variables. +- **`workspace`** + - Whitespaces and `#`, `$` characters are disallowed. + - GNU make variable or function references (`$`) are disallowed. + +## Future work, contributing and omissions + +Several features were left temporarily or intentionally unimplemented in the current version of the module, however, they may be useful in certain cases. + +If your project depends on something missing from the module, feel free to open an issue, and we'll discuss how the needed functionality can be added to the module in a convenient and flexible way — or submit a pull request with the implementation! + +Note that the general preference is to use existing Premake settings wherever possible — potentially twisting them and adding the necessary constraints while still trying to keep the original semantic concepts — instead of adding new ones. Don't hesitate to exploit filters, to interpret a variable in different ways depending on the target ABI and overall context, to use any opportunity to make the module more compatible with existing projects for other targets. However, if new settings need to be added, prefer using `kind = "boolean"` settings rather than flags as the former have three states, making it easier to provide default behavior, especially if the new settings are promoted to the Premake core or used in other modules in the future, potentially on platforms with different defaults. + +If you're adding functionality that involves strings in a new place in the generated Android.mk and Application.mk files, make sure to check which non-letter ASCII characters, including different types of whitespaces, are supported by ndk-build in the specific context, especially if it's a file name or a path, on both Linux (which allows any characters in paths) and Windows (including UNC paths), with attention to backslash-escaping of shell-interpreted characters (see `androidndk.shellEscapedCharactersPostQuotes`), but not only them. All user input must be passed through `p.esc`, preferably early (and functions expecting output of `p.esc` as arguments must be named with the `PostEsc` suffix), to ensure the integrity of GNU make variable or function references (also make sure that paths including `$` references are handled correctly as absolute or as relative depending on the context, especially when joining — usually paths beginning with `$` should be considered absolute, and that's how Premake itself treats them, while a relative path needs to start with `./$` in this case) and of escaping of the comment character `#`. After `p.esc`, the invalid character check may be done for the non-reference part of the string if needed — see the usage `androidndk.staticallyHasPatternPostEsc` (build-time validation would be an overkill if there are references in the string, but to catch potential errors when porting projects from other platforms, generation-time checks are useful). In many places, strings are used in shell commands invoked by ndk-build — see how checkers and escapers starting with `androidndk.shellEscape` are used in the module; also shell character escaping needs to be done at build time, not at Premake invocation time, since it must be performed after expanding GNU make references. Also, if you're passing user input to a GNU make function, use an intermediate variable (see `androidndk.getTemporaryVariableReference`), as the user-provided string may contain brackets or commas, which would break the parsing of the function call. + +The following functionality has been omitted currently, but may be nice to have for reasons like compatibility: + +- Unit tests. This is a large module with complex input handling with a large number of edge cases for many settings that, in some cases, depend on the kind of the project, the target ABIs, source languages used in the project — written in a dynamically-typed language. Many errors and typos may occur. Tests verifying both supported and disallowed input need to be added — covering platform-dependent and platform-agnostic projects, ABI-dependent and ABI-agnostic projects, different kinds of binaries, prebuilt libraries, external Android.mk projects, source files written in various languages with extension filters and `.arm` and `.neon` suffixes, link settings and transitivity of them across chains of static libraries where needed, GNU make variable and function references, disallowed characters, shell-interpreted character escaping, and other cases handled by this module. +- Building for deprecated ABIs removed from the NDK — `armeabi`, `armeabi-v7a-hard`, `mips`, `mips64`. While simply adding a new `architecture` is trivial (though for choosing `armeabi-v7a-hard`, a special setting for the floating-point argument convention may be more suitable), that wouldn't imply complete support for the details of them — such as instruction set extensions (like the MXU vector extensions for MIPS), hardware floating-point unit support. MIPS-powered Android devices are extremely rare, and ARMv5 deprecation began in Android 4.0, having been completed in Android 4.4. +- Support for obsolete toolchains removed from the NDK, such as GCC, as well as toolchain version selection (as of r23, the NDK only offers one version of the Clang toolchain). +- Clang-Tidy — needs to be integrated into the architecture of Premake itself. +- Post-processing of the generated machine code and assembly source files via `LOCAL_FILTER_ASM` — needs to be added in a way friendly to the Premake architecture. +- Compatibility with the Visual Studio actions for Android (the built-in `android` module). It defines many settings in ways that aren't consistent with the Premake core itself, as well as adding redundant options: + - Values are generally lowercase, while the Premake core uses PascalCase internally. + - The additions to the list of the allowed `architecture` values are chaotic. For `armeabi`, it allows both `"arm"` and `"armv5"` (which are registered as separate options rather than aliases of each other), while for `armeabi-v7a`, it uses `"armv7"`. Premake itself provides an `"ARM"` option, which, given the removal of ARMv5 support from the NDK, is more likely to be expected to correspond to ARMv7 as opposed to ARMv5. `arm64-v8a` is exposed as `"aarch64"` instead of `"ARM64"` used in the Premake core. + - ARMv5 and ARMv7 instruction sets are presented as two options: a `"Thumb"` flag, and a `"thumbmode"` setting, with one of the allowed values being `"disabled"` rather than `"Default"` commonly used in Premake. + - `stl` is a new setting in it, but it uses misleading names. The `"gnustl"` and `"c++"` standard libraries provided by ndk-build are called `"gnu"` and `"libc++"` instead, which is likely not what users expect. For `"system"`, the value `"none"` is used — however, the NDK has both `"system"` (which is deprecated) and `"none"`, the difference between the two being `new` and `delete` being supported in `"system"`, while `"none"` providing no C++ standard library functionality at all. The name `stl` also doesn't imply C++ directly, which may cause issues if Premake gets support for a different language that also has the standard library referred to by the same acronym — unlike settings like `buildoptions`, this may be even workspace-level (and in ndk-build, it is), and thus the value is not file- or extension-filterable. + - `androidapilevel` is redundant due to the existence of `systemversion`. + - The `"posix"` system tag is not added for Android. +- The “call array” architecture is not used in the code as certain settings are handled in multiple places in different ways, and various kinds of preprocessing are done. Replacing parts of the generation code in project scripts is unlikely to be useful or convenient for this reason. diff --git a/src_rebuild/premake_modules/androidndk/UNLICENSE.txt b/src_rebuild/premake_modules/androidndk/UNLICENSE.txt new file mode 100644 index 00000000..68a49daa --- /dev/null +++ b/src_rebuild/premake_modules/androidndk/UNLICENSE.txt @@ -0,0 +1,24 @@ +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. + +For more information, please refer to diff --git a/src_rebuild/premake_modules/androidndk/_manifest.lua b/src_rebuild/premake_modules/androidndk/_manifest.lua new file mode 100644 index 00000000..01def5e8 --- /dev/null +++ b/src_rebuild/premake_modules/androidndk/_manifest.lua @@ -0,0 +1,11 @@ +-- premake-androidndk - a multi-ABI, multi-language ndk-build Android.mk generator for Premake. +-- Originally written by Vitaliy Kuzmin. +-- See README.md for detailed usage and design information. +-- Available under the Unlicense (see UNLICENSE.txt) or the BSD 3-Clause "New" or "Revised" License (see LICENSE.txt). + +return { + "_preload.lua", + "androidndk.lua", + "androidndk_project.lua", + "androidndk_workspace.lua", +}; diff --git a/src_rebuild/premake_modules/androidndk/_preload.lua b/src_rebuild/premake_modules/androidndk/_preload.lua new file mode 100644 index 00000000..e66cfbfb --- /dev/null +++ b/src_rebuild/premake_modules/androidndk/_preload.lua @@ -0,0 +1,110 @@ +-- premake-androidndk - a multi-ABI, multi-language ndk-build Android.mk generator for Premake. +-- Originally written by Vitaliy Kuzmin. +-- See README.md for detailed usage and design information. +-- Available under the Unlicense (see UNLICENSE.txt) or the BSD 3-Clause "New" or "Revised" License (see LICENSE.txt). + +local p = premake; + +p.api.addAllowed("system", p.ANDROID); +-- NEON is enabled by default, like in NDK r21. +-- Similar to how Premake defines "IA32" for x86, use "ARMv7" to disable NEON (and use the .neon suffix where needed). +p.api.addAllowed("vectorextensions", { "ARMv7", "NEON", "SSE4.2" }); +if os.systemTags[p.ANDROID] == nil then + os.systemTags[p.ANDROID] = { "android", "posix", "mobile" }; +end + +p.api.register({ + name = "armisa", + scope = "config", + kind = "string", + allowed = { + p.DEFAULT, + "A32", + "T32", + }, +}); + +p.api.register({ + name = "cppstl", + scope = "config", + kind = "string", + allowed = { + p.DEFAULT, + -- As of NDK r18, only none, c++ and system are available, with the latter being deprecated. + -- Supporting the older STLs is trivial, however. + "c++", + "gabi++", + "gnustl", + "none", + "stlport", + "system", + }, +}); + +p.api.register({ + name = "formatstringchecks", + scope = "config", + kind = "boolean", +}); + +p.api.register({ + name = "renderscriptcompatibility", + scope = "config", + kind = "boolean", +}); + +p.api.register({ + name = "renderscriptincludedirsoverride", + scope = "config", + kind = "boolean", +}); + +p.api.register({ + name = "shortcommands", + scope = "config", + kind = "boolean", +}); + +p.api.register({ + name = "thinarchive", + scope = "config", + kind = "boolean", +}); + +p.api.register({ + name = "undefinedsymbols", + scope = "config", + kind = "boolean", +}); + +-- Whether this static library project should be linked as a whole, even if not specified in `wholelibs` of dependent projects. +p.api.register({ + name = "wholelib", + scope = "config", + kind = "boolean", +}); + +-- Subset of `links` which need to be linked as a whole regardless of their `wholelib` setting. +p.api.register({ + name = "wholelibs", + scope = "config", + kind = "list:mixed", + tokens = true, +}); + +newaction({ + trigger = "androidndk", + shortname = "Android ndk-build", + description = "Generate Android ndk-build makefiles", + targetos = p.ANDROID, + valid_kinds = { p.CONSOLEAPP, p.SHAREDLIB, p.STATICLIB }, + valid_languages = { p.C, p.CPP }, + -- Premake workspace and project names can include periods, so using suffixes for both. + onWorkspace = p.modules.androidndk.onWorkspace, + onProject = p.modules.androidndk.onProject, +}); + +-- Decide when the full module should be loaded. +return function(config) + return _ACTION == "androidndk"; +end; diff --git a/src_rebuild/premake_modules/androidndk/androidndk.lua b/src_rebuild/premake_modules/androidndk/androidndk.lua new file mode 100644 index 00000000..549e9915 --- /dev/null +++ b/src_rebuild/premake_modules/androidndk/androidndk.lua @@ -0,0 +1,465 @@ +-- premake-androidndk - a multi-ABI, multi-language ndk-build Android.mk generator for Premake. +-- Originally written by Vitaliy Kuzmin. +-- See README.md for detailed usage and design information. +-- Available under the Unlicense (see UNLICENSE.txt) or the BSD 3-Clause "New" or "Revised" License (see LICENSE.txt). + +local p = premake; +p.modules.androidndk = {}; +local androidndk = p.modules.androidndk; +androidndk._VERSION = "1.0.0"; + +include("androidndk_project.lua"); +include("androidndk_workspace.lua"); + +include("_preload.lua"); + +-- Inserts one or multiple values into a table. +-- Useful for inserting compiler flags from built-in Premake toolsets. +function androidndk.insertKeyedFlat(tbl, value) + -- Skip if the value is nil, for instance, to quickly ignore irrelevant flags or values of settings without a mapping. + if value == nil then + return; + end + if type(value) == "table" then + for i, element in ipairs(value) do + androidndk.insertKeyedFlat(tbl, element); + end + return; + end + if tbl[value] ~= nil then + return; + end + table.insert(tbl, value); + tbl[value] = value; +end + +-- Rules regarding special characters in the input and how they're handled in this module (as of NDK r23, checked with `$(warning "$(VARIABLE)")`): +-- * Whitespaces (tab, vertical tab, form feed, space) - defining the word "whitespace" as all of these, unlike just "space": +-- * Horizontal tab being the first on a line defines a recipe. +-- * Otherwise, all whitespace characters behave like whitespaces, at least in the syntax of GNU make itself. +-- * Trimming behavior in various contexts relevant to Android.mk: +-- * All sides of a variable assignment - left-hand, the operator itself, right-hand - have leading whitespaces trimmed. +-- * In the right-hand side of a variable assignment, each line (separated with a \-escaped newline) is treated as a list element, like a complete token. +-- Any amount (including zero) of whitespaces or escaped newlines between two non-empty elements is collapsed into a single " " space. +-- However, if the last non-whitespace character in an element is $ (not $$, but $ alone), no space is inserted, they're just removed (including the $). +-- This rule, however, is directly applicable only to inner newline separators, not the beginning or the end of the whole right-hand side. +-- Whitespaces and newlines before the first non-empty element are trimmed (as leading whitespaces in general). +-- Behavior for the last element is less consistent. +-- If the last non-empty element is followed only by whitespaces, all those trailing whitespaces are preserved as their original encoding. +-- If there's a \-escaped newline after the last non-empty element, however, all trailing whitespaces and newlines are collapsed into one " " space. +-- Within the boundaries of one list element, however, all original whitespaces are preserved. +-- * Function call argument lists (as a whole, not individual arguments) have leading whitespaces trimmed. +-- * $() can be prepended or appended to include leading or trailing whitespaces in an element or the first function argument. +-- * Resolution: +-- * Pass through directly. +-- * Single-line variable generation: +-- * Preserve project-provided leading whitespaces for the whole value (or the first table element) using $(). +-- * Multiline list variable generation: +-- * Preserve project-provided leading and trailing whitespaces for each table element using $(), though not necessary for the last. +-- * Both "\" and " \" are fine for separating table elements. +-- However, using " \" is consistent with the general recipe line splitting rules of GNU make for joining with a space. +-- * Newline characters (carriage return, line feed): +-- * Start a new statement. +-- * Can be escaped with a backslash, but then the newline itself may be trimmed according to the whitespace trimming rules. +-- * True newlines can be kept in variable declarations using define/endef. +-- * Resolution: +-- * Replace unconditionally with spaces. +-- * Escaping handled separately. +-- * Not using define/endef until a real use in ndk-build scripts is found. +-- * Backslash: +-- * If the last character before a newline, behaves as a line split, trimmed according to the whitespace trimming rules. +-- * Escapes the number sign which starts a comment. +-- * In other cases, passed as a raw character. +-- * Resolution: +-- * Pass through directly. +-- * If the last character on a line and provided by the project, append $(). +-- * Dollar sign: +-- * A single dollar sign is a prefix for a variable or a function reference. +-- * $(name arguments) and ${name arguments} are the regular syntax. +-- * If neither () nor {} are used, one character immediately following the $ is used as the variable name. +-- * $ alone directly in the end of a variable assignment is treated as a raw $ character. +-- * The effect of a trailing $ on variable assignments split into multiple lines is described in the section about whitespaces. +-- * $$ results in a raw $ character. +-- * Resolution: +-- * Pass through directly to allow using environment variables and built-in variables like TARGET_ARCH_ABI in scripts, as well as functions. +-- * Prevent unclosed variable and function references with an undefined, but safe result. +-- The easiest way is to close them - doesn't require insertion into the middle - with a special case for the trailing $ (convert to $$). +-- * Number sign: +-- * Starts a comment. +-- * Escaped with a backslash for passing as raw data, but the backslash itself may be escaped as well. +-- * Backslashes preceding a # are treated as n/2 backslashes ((n-1)/2 if there is an odd number of them) in other cases. +-- * An even number of backslashes before the # in the original file causes the comment not to be escaped. +-- * Resolution: +-- * Escape with a single backslash and a terminator to prevent dependence on the number of backslashes, as $()\#. +-- * This makes concatenation of a string ending with \ and one starting with an escaped # safe. + +androidndk.commentEscapeString = "$()\\#"; +androidndk.commentUnescapePattern = string.escapepattern(androidndk.commentEscapeString); + +androidndk.whitespacesNonNewline = { + ["\t"] = "\t", + ["\v"] = "\v", + ["\f"] = "\f", + [" "] = " ", +}; + +-- Due to escaping of #, this function can't be called again on its result. +function androidndk.esc(value) + value = string.gsub(value, "#", androidndk.commentEscapeString); + -- Replace newlines with safer spaces. + value = string.gsub(value, "\r\n", " "); + value = string.gsub(value, "\n", " "); + value = string.gsub(value, "\r", " "); + -- Make sure there are no unclosed variable and function references. + -- Close $() and ${} with a bracket, and escape the final $. + -- As a result, all references will be closed and balanced. + local unclosedReferenceTerminators = {}; + local afterReferenceCharacter = false; + -- Need a while loop as the for loop counter can't be modified from the body. + local i = 1; + while i <= string.len(value) do + local character = string.sub(value, i, i); + if character == "\\" and string.sub(value, i + 1, i + 1) == "#" then + -- Escaped comment character. + i = i + 1; + character = "#"; + end + if afterReferenceCharacter then + -- The character after the $. + -- Options: $ (escaped raw $), an opening bracket (opening a reference), any other character (single-character reference). + if character == "(" then + table.insert(unclosedReferenceTerminators, ")"); + elseif character == "{" then + table.insert(unclosedReferenceTerminators, "}"); + end + afterReferenceCharacter = false; + else + -- Not the character after the $. + -- Options: $, a reference-closing bracket, any other raw character. + if character == "$" then + afterReferenceCharacter = true; + elseif #unclosedReferenceTerminators > 0 and character == unclosedReferenceTerminators[#unclosedReferenceTerminators] then + unclosedReferenceTerminators[#unclosedReferenceTerminators] = nil; + end + end + i = i + 1; + end + local referencesClosed = { value }; + -- Escape the incomplete single-character reference as a raw $. + if afterReferenceCharacter then + table.insert(referencesClosed, "$"); + end + -- Close the unclosed references. + for i2 = 1, #unclosedReferenceTerminators do + table.insert(referencesClosed, unclosedReferenceTerminators[#unclosedReferenceTerminators - i + 1]); + end + return table.concat(referencesClosed); +end + +function androidndk.setupGeneration() + -- The tab character is the recipe line prefix in makefiles. + p.indent(" "); + p.escaper(androidndk.esc); + p.eol("\n"); +end + +-- Whether the string contains GNU make variable or function references. +-- p.esc should be done prior to this. +-- Empty references, that are $() or ${}, are not treated as references, merely as delimiters. +-- $() is used in comment sign escaping, for example. +function androidndk.hasNonEmptyMakeReferencesPostEsc(value) + -- For strictness and simplicity, the lone trailing $ is treated as a reference too (can't be a result of p.esc anyway). + local i = 0; + while true do + i = string.find(value, "%$", i + 1); + if i == nil then + return false; + end + if string.sub(value, i, i + 1) == "$$" then + i = i + 1; + else + local potentiallyEmptyReference = string.sub(value, i, i + 2); + if potentiallyEmptyReference == "$()" or potentiallyEmptyReference == "${}" then + i = i + 2; + else + return true; + end + end + end +end + +-- Removes variable and function references and reverts p.esc's escaping of # and $ from a GNU make variable value (but not multiline). +-- Useful for coarse validation of string contents, whether there are unsupported characters. +-- What the references expand to isn't known at Premake time, but static value validation may be good to catch common issues. +-- To get a value that can be passed back to GNU make, do string.gsub of the "%$" pattern to "$$", and then p.esc. +-- For strictness and simplicity, the lone trailing $ is treated as a reference too (can't be a result of p.esc anyway). +function androidndk.unescapeAndRemoveMakeReferencesPostEsc(value) + -- Unescape p.esc's escaping of the comment character. + value = string.gsub(value, androidndk.commentUnescapePattern, "#"); + local newValue = {}; + local unclosedReferenceTerminators = {}; + local afterReferenceCharacter = false; + for i = 1, string.len(value) do + local character = string.sub(value, i, i); + if afterReferenceCharacter then + -- The character after the $. + -- Options: $ (escaped raw $), an opening bracket (opening a reference), any other character (single-character reference). + if character == "$" then + if not (#unclosedReferenceTerminators > 0) then + -- Escaped $. + table.insert(newValue, "$"); + end + elseif character == "(" then + table.insert(unclosedReferenceTerminators, ")"); + elseif character == "{" then + table.insert(unclosedReferenceTerminators, "}"); + end + afterReferenceCharacter = false; + else + -- Not the character after the $. + -- Options: $, a reference-closing bracket, any other raw character. + if character == "$" then + afterReferenceCharacter = true; + else + if #unclosedReferenceTerminators > 0 then + if character == unclosedReferenceTerminators[#unclosedReferenceTerminators] then + unclosedReferenceTerminators[#unclosedReferenceTerminators] = nil; + end + else + -- A raw character outside references. + table.insert(newValue, character); + end + end + end + end + return table.concat(newValue); +end + +function androidndk.staticallyHasPatternPostEsc(value, pattern) + return string.find(androidndk.unescapeAndRemoveMakeReferencesPostEsc(value, true), pattern) ~= nil; +end + +-- Characters that can be escaped with a backslash in Windows shell commands, except for \ itself and ". +-- \ and " should be escaped before these inside individual arguments as they may be wrapped in " by the module itself to include whitespaces. +-- On Windows, before other characters (except for \ and "), a \ is kept and treated as a directory separator instead. +-- Extracted by using all characters 33-126 (with special rules for #) prefixed with \ in a -Define and seeing the Clang error for its usage. +-- Matches Windows sh_chars_sh in GNU make, with the addition of a single quote. +-- On Linux, where \ is not a path separator, prefixing any character with \ results in it being escaped in the shell. +androidndk.shellEscapedCharactersPostQuotes = { + "#", "$", "&", "'", "(", ")", "*", ";", "<", ">", "?", "[", "]", "^", "`", "{", "|", "}" +}; + +-- Checkers are meant to be used in assignToVariablePostEsc calls, and assume the input is pre-escaped and doesn't contain non-empty references. + +function androidndk.shellEscapePostQuotesChecker(value) + -- Comments are escaped as $()\# - contains an empty reference. + -- However, this still includes the # itself, which needs to be escaped with a backslash in a shell command. + -- Raw dollar signs ($$ representing $) need to be escaped in a shell command too. + if string.find(value, "#") ~= nil or string.find(value, "%$%$") ~= nil then + return true; + end + -- Remove empty references to check if the value contains (){}. + -- It's assumed that these are the only kind of references that may be passed to checkers. + value = string.gsub(string.gsub(value, "%$%(%)", ""), "%${}", ""); + return string.find(value, "[&'%(%)%*;<>%?%[%]%^`{|}]") ~= nil; +end + +function androidndk.shellEscapeChecker(value) + -- The only two usages of a backslash after androidndk.esc are a raw backslash and a # escape sequence. + -- Both \ and # need to be escaped with \ in the shell. + -- So, it's okay to return true if there is any \ at all. + if string.find(value, "[\\\"]") ~= nil then + return true; + end + return androidndk.shellEscapePostQuotesChecker(value); +end + +function androidndk.shellEscapeModuleFileNameChecker(value) + -- : must be \-escaped on Linux. + -- It's a drive letter separator on Windows, however, so it's disallowed in LOCAL_MODULE_FILENAME there (it's a name, not a path). + if string.find(value, "[:]") ~= nil then + return true; + end + return androidndk.shellEscapeChecker(value); +end + +function androidndk.shellEscapeSrcFilesChecker(value) + -- : must be \-escaped on Linux, but cannot be escaped on non-Cygwin Windows, and is a drive letter separator there supported directly. + -- The differences are handled at build time according to $(HOST_OS). + if string.find(value, "[:]") ~= nil then + return true; + end + return androidndk.shellEscapeChecker(value); +end + +-- Using UPPER_CASE names because ndk-build reserves all lower-case names. +androidndk.shellEscapePreQuotesMakeCall = "PREMAKE_ANDROIDNDK_SHELL_ESCAPE_PRE_QUOTES"; +androidndk.shellEscapePostQuotesMakeCall = "PREMAKE_ANDROIDNDK_SHELL_ESCAPE_POST_QUOTES"; +androidndk.shellEscapeMakeCall = "PREMAKE_ANDROIDNDK_SHELL_ESCAPE"; +androidndk.shellEscapeModuleFileNameMakeCall = "PREMAKE_ANDROIDNDK_SHELL_ESCAPE_MODULE_FILENAME"; +androidndk.shellEscapeSrcFilesMakeCall = "PREMAKE_ANDROIDNDK_SHELL_ESCAPE_SRC_FILES"; + +androidndk.temporaryVariablePrefix = "PREMAKE_ANDROIDNDK_TEMPORARY_"; + +-- Gets or adds a temporary intermediate GNU make variable. +-- Useful for wrapping strings in GNU make function calls, for safety if they contain the closing bracket. +function androidndk.getTemporaryVariableReference(temporaryVariables, value) + local index = temporaryVariables[value]; + if index == nil then + index = #temporaryVariables + 1; + temporaryVariables[index] = value; + temporaryVariables[value] = index; + end + return "$(" .. androidndk.temporaryVariablePrefix .. index .. ")"; +end + +function androidndk.getCaseElse(anyCasesWritten) + if anyCasesWritten then + return "else "; + end + return ""; +end + +-- ABIs that be set by a combination of settings that can be expressed in a project. +-- With the architecture set to "universal" or nil, projects can be built for ABIs not in this list though. +-- If new ABIs are added to the NDK, they can be supported without updating this module at least in ABI-agnostic projects. +-- Sorted alphabetically. +androidndk.knownAbis = { + "arm64-v8a", + -- "armeabi" (ARMv5) was removed in NDK r17. + "armeabi-v7a", + -- "armeabi-v7a-hard" was removed in NDK r12. + -- Building for both calling conventions at once (if passing this table to APP_ABI) would be pointless anyway. + -- "mips" and "mips64" were removed in NDK r17. + -- Premake has no built-in architecture values for MIPS. + "x86", + "x86_64", +}; + +androidndk.ABI_ALL = "all"; + +androidndk.architectureAbis = { + [p.ARM] = "armeabi-v7a", + [p.ARM64] = "arm64-v8a", + [p.X86] = "x86", + [p.X86_64] = "x86_64", +}; + +-- Returns: +-- * The ABI name for supported configurations. +-- * "all" (like the "all" that can be passed to APP_ABI) if the configuration doesn't have an ABI filter. +-- * nil for unsupported configurations. +function androidndk.getConfigAbi(config) + -- While armeabi (ARMv5) and armeabi-v7a (ARMv7) may be both considered "ARM", ARMv5 is different enough to have its own `architecture` option. + -- Support for ARMv5, however, was removed in NDK r17. + -- If needed, it can be exposed via a separate configuration variable. + -- MIPS support was also removed in r17. + if config.architecture == nil or config.architecture == p.UNIVERSAL then + return androidndk.ABI_ALL; + end + return androidndk.architectureAbis[config.architecture]; +end + +function androidndk.preventWhitespaceTrimming(value) + if androidndk.whitespacesNonNewline[string.sub(value, 1, 1)] ~= nil then + -- Prevent trimming of the leading whitespaces. + value = "$()" .. value; + end + local trailingCharacter = string.sub(value, -1, -1); + if trailingCharacter == "\\" or androidndk.whitespacesNonNewline[trailingCharacter] ~= nil then + -- Don't treat the final backslash (like in a directory path) as line splitting. + -- Also prevent trimming of the trailing whitespaces. + value = value .. "$()"; + end + return value; +end + +-- Returns whether the post-processing call is needed for any element. +function androidndk.assignToVariablePostEsc(name, value, multiline, postProcessChecker, operator) + if operator == nil then + operator = ":="; + end + if type(value) == "string" then + value = { value }; + end + value = table.filterempty(value); + if not (#value > 0) then + return false; + end + local postProcessNeeded = false; + if multiline then + p.push("%s %s \\", name, operator); + for i, element in ipairs(value) do + local boundedLine = androidndk.preventWhitespaceTrimming(element); + if i >= #value then + p.w(boundedLine); + else + p.w("%s \\", boundedLine); + end + -- Post-processing is always needed if there are references because they are expanded to anything at runtime. + -- However, if not needed, don't waste build time doing unnecessary substitutions. + if postProcessChecker ~= nil and not postProcessNeeded and (androidndk.hasNonEmptyMakeReferencesPostEsc(element) or postProcessChecker(element)) then + postProcessNeeded = true; + end + end + p.pop(); + else + -- Inner whitespaces are preserved within the right-hand side of an assignment, safe to concatenate. + p.w("%s %s %s", name, operator, androidndk.preventWhitespaceTrimming(table.concat(value, " "))); + end + return postProcessNeeded; +end + +function androidndk.writePostProcessCall(variableName, makeCall) + p.w("%s := $(call %s,$(%s))", variableName, makeCall, variableName); +end + +function androidndk.isConfigSupported(config, reportWarnings) + if config.flags.ExcludeFromBuild then + -- Intentionally excluded. + -- Warnings specific to this module shouldn't be reported either as the configuration may not be targeting this module at all. + return false; + end + if config.project ~= nil then + assert(androidndk.isProjectSupported(config.project, false), "Usage of configurations for unsupported projects must not be attempted at all"); + end + -- Wrong kind or ABI are a normal situation when the project has both Android and non-Android configs. + -- Not reporting warnings for them (or any warnings as for non-Android targets these issues may be non-existent). + if androidndk.kindScripts[config.kind] == nil or androidndk.getConfigAbi(config) == nil then + return false; + end + local warningLocation; + if reportWarnings then + if config.project ~= nil then + warningLocation = string.format("workspace '%s' project '%s' configuration '%s'", config.workspace.name, config.project.name, config.name); + else + warningLocation = string.format("workspace '%s' configuration '%s'", config.workspace.name, config.name); + end + end + local configSupported = true; + -- Whitespaces because configurations are placed in a whitespace-separated list. + -- % because configurations and platforms are used in filter and filter-out, where % is a wildcard. + -- It can be escaped with \, but then the case when the % is preceded by other backslashes is complicated to handle. + -- The rest are disallowed due to usage of the names in GNU make function calls. + local disallowedCharacters = "%(),"; + local disallowedPattern = "[%s%%%(%),]"; + if androidndk.staticallyHasPatternPostEsc(p.esc(config.buildcfg), disallowedPattern) then + configSupported = false; + if reportWarnings then + p.warn( + "Skipping %s with configuration name containing whitespaces or disallowed characters %s", + warningLocation, disallowedCharacters); + end + end + if config.platform ~= nil and androidndk.staticallyHasPatternPostEsc(p.esc(config.platform), disallowedPattern) then + configSupported = false; + if reportWarnings then + p.warn( + "Skipping %s with platform name containing whitespaces or disallowed characters %s", + warningLocation, disallowedCharacters); + end + end + return configSupported; +end + +return androidndk; diff --git a/src_rebuild/premake_modules/androidndk/androidndk_project.lua b/src_rebuild/premake_modules/androidndk/androidndk_project.lua new file mode 100644 index 00000000..b310ecad --- /dev/null +++ b/src_rebuild/premake_modules/androidndk/androidndk_project.lua @@ -0,0 +1,1743 @@ +-- premake-androidndk - a multi-ABI, multi-language ndk-build Android.mk generator for Premake. +-- Originally written by Vitaliy Kuzmin. +-- See README.md for detailed usage and design information. +-- Available under the Unlicense (see UNLICENSE.txt) or the BSD 3-Clause "New" or "Revised" License (see LICENSE.txt). + +local p = premake; +local androidndk = p.modules.androidndk; + +androidndk.kindScripts = { + [p.CONSOLEAPP] = "BUILD_EXECUTABLE", + [p.SHAREDLIB] = "BUILD_SHARED_LIBRARY", + [p.STATICLIB] = "BUILD_STATIC_LIBRARY", +}; + +androidndk.prebuiltKinds = { + [p.SHAREDLIB] = { + extension = ".so", + script = "PREBUILT_SHARED_LIBRARY", + }, + [p.STATICLIB] = { + extension = ".a", + script = "PREBUILT_STATIC_LIBRARY", + }, +}; + +function androidndk.isProjectSupported(project, reportWarnings) + -- Not allowing references or escaped $ in project names as they complicate path building as well as including project Android.mk files. + -- Premake treats any path beginning with $ as absolute. + -- LOCAL_MODULE and LOCAL_STATIC_LIBRARIES sweeping result: + -- Allowed directly on Linux: !+,-./@[]^_{}~ + -- Allowed if \-escaped on Linux: "` + -- Allowed if \-escaped on Linux, misleadingly displayed with \ in the terminal: &'()*<>? + -- Allowed if \\-escaped on Linux: \ + -- Disallowed: whitespaces, #$%:;=| + -- Stricter than LOCAL_MODULE_FILENAME derived from it by default for : and = (no action required). + -- However, more relaxed for / - to avoid issues, disallowing / too. + if string.find(project.name, "%$") ~= nil or androidndk.staticallyHasPatternPostEsc(p.esc(project.name), "[%s#%$%%/:;=|]") then + if reportWarnings then + p.warn( + "Skipping workspace '%s' project '%s' with name containing GNU make references, " .. + "whitespaces or characters disallowed in an ndk-build module name #$%%/:;=|", + project.workspace.name, project.name); + end + return false; + end + return true; +end + +function androidndk.getConfigCondition(buildcfg, platform, abi) + -- All requirements must be met by what is provided by ndk-build and the user for a configuration to be selected. + -- This is done by removing (filtering out) the current state from the set of the requirements. + -- If the resulting set is empty, the current state matches all the requirements. + + -- It's important that either all requirements are checked at once (like here), or the ABI check is the outermost ifeq. + -- PREMAKE_ANDROIDNDK_CONFIGURATIONS and _PLATFORMS include _all_ needed configurations and are the same throughout the ndk-build execution. + -- With nested buildcfg > platform > ABI conditionals, all ABIs would be entering the same buildcfg, and then the same platform within it. + -- However, the ABI is the primary criteria for selecting the platform (and the buildcfg if it depends on it). + -- The ABI should be narrowing down the selection either to one config, or to skipping the module. + -- The result for multiple configurations for one ABI is undefined. + + local state = {}; + local requirements = {}; + + -- Configs in projects are usually sorted by ABI (so ABI-agnostic fallbacks can be provided), then (by Premake) buildcfg, then platform. + -- So, using this order as well for better readability of generated makefiles. + + -- ABI filtering is done only when the ABI specified. + if abi ~= nil then + if abi ~= androidndk.ABI_ALL then + table.insert(state, "ABI=$(TARGET_ARCH_ABI)"); + table.insert(requirements, "ABI=" .. abi); + end + end + + -- At least one build configuration is required by Premake. + table.insert(state, "$(PREMAKE_ANDROIDNDK_CONFIGURATIONS_PREFIXED)"); + table.insert(requirements, "CONFIGURATION=" .. p.esc(buildcfg)); + + -- Platforms may be unspecified, in this case, configurations will have a nil platform. + if platform ~= nil then + table.insert(state, "$(PREMAKE_ANDROIDNDK_PLATFORMS_PREFIXED)"); + table.insert(requirements, "PLATFORM=" .. p.esc(platform)); + end + + return "ifeq ($(filter-out " .. table.concat(state, " ") .. "," .. table.concat(requirements, " ") .. "),)"; +end + +function androidndk.configUsesA32(config) + -- LOCAL_ARM_MODE and the .arm suffix have no effect on ABIs where they're not relevant - no need to check the ABI. + -- NDK uses T32 by default, and always switches to A32 for debug builds, but it's handled implicitly in it. + return config.armisa == "A32"; +end + +function androidndk.configUsesNeon(config) + -- LOCAL_ARM_NEON and the .neon suffix have no effect on ABIs where they're not relevant - no need to check the ABI. + -- On NDK r21, NEON is enabled by default. + -- Requiring setting vectorextensions to "ARMv7" (similar to "IA32") explicitly for disabling. + return config.vectorextensions ~= "ARMv7"; +end + +function androidndk.shellEscapePreQuotesPostEsc(argument, temporaryVariables) + if androidndk.hasNonEmptyMakeReferencesPostEsc(argument) then + -- Escape while building, after expanding variable and function references. + -- Can't use the text directly in a function call because it may contain brackets. + return "$(call " .. androidndk.shellEscapePreQuotesMakeCall .. "," .. androidndk.getTemporaryVariableReference(temporaryVariables, argument) .. ")"; + end + -- Unescape comment characters, which have \ in their escape sequence. + argument = string.gsub(argument, androidndk.commentUnescapePattern, "#"); + -- Pre-escape. + argument = string.gsub(string.gsub(argument, "\\", "\\\\"), "\"", "\\\""); + -- Re-escape comment characters. + argument = string.gsub(argument, "#", androidndk.commentEscapeString); + return argument; +end + +-- For calling with unescaped paths, otherwise paths starting with # will be considered absolute due to $()\# escaping. +-- In addition, may need to escape characters inserted by path.getrelative itself. +-- Unfortunately, if path.getrelative inserts any $ by itself while joining, they will be treated as references. +-- They wouldn't be able to be distinguished from references specified in the project itself. +function androidndk.getEscapedProjectRelativePath(project, file, joinWithLocalPath) + -- Must be synchronized with LOCAL_PATH setting. + -- Based on p.filename logic (relative to the location of the project's Android.mk). + -- If a path starts with a GNU make variable or function reference, it's assumed to be absolute, to allow using paths like $(NDK_ROOT). + -- Premake already treats paths starting with $ as absolute in path.getrelative, among other functions. + -- Relative paths starting with $ must be prefixed with ./. + local relativePath = path.getrelative(project.location or project.basedir, file); + -- For something like ./$(VARIABLE) (relative), path.getrelative can possibly return $(VARIABLE), which will be treated as absolute. + -- Premake treats all paths beginning with $ as absolute. + -- In this case, the path must still be written as relative to $(LOCAL_PATH), but path.join won't work. + -- path.join doesn't even work if the trailing part begins with ./$(VARIABLE). + -- Using concatenation for this purpose instead. + if joinWithLocalPath and (not path.isabsolute(relativePath) or (string.sub(relativePath, 1, 1) == "$" and string.sub(file, 1, 1) ~= "$")) then + relativePath = "$(LOCAL_PATH)/" .. relativePath; + end + return p.esc(relativePath); +end + +-- Excluding the .arm and .neon suffixes. +androidndk.asmExtension = ".asm"; +androidndk.cExtension = ".c"; +androidndk.sourceExtensions = { androidndk.asmExtension, androidndk.cExtension }; +androidndk.compilerFlagsVariables = { + [androidndk.asmExtension] = "ASMFLAGS", + [androidndk.cExtension] = "CONLYFLAGS", +}; +-- NDK r23 default-c++-extensions. +-- Strictly broader than path.iscppfile as of premake-core v5.0.0-alpha16. +-- path.iscppfile is not usable directly conveniently, however, as it also includes assembly and Objective-C/C++. +-- Do not use path.hasextension (or path.iscppfile) as it's case-insensitive unlike ndk-build, and will treat .C as C instead of C++. +-- Indexed for concatenation purposes. +androidndk.cppExtensions = { ".cc", ".cp", ".cxx", ".cpp", ".CPP", ".c++", ".C" }; +table.foreachi(androidndk.cppExtensions, function(extension) + -- Build a hash set for lookup in cppExtensions. + androidndk.cppExtensions[extension] = extension; + -- Register the extension as a C++ one. + table.insert(androidndk.sourceExtensions, extension); + androidndk.compilerFlagsVariables[extension] = "CPPFLAGS"; +end); +-- NDK r23 default-rs-extensions. +androidndk.rsExtensions = { ".rs", ".fs" }; +table.foreachi(androidndk.rsExtensions, function(extension) + -- Build a hash set for lookup in rsExtensions. + androidndk.rsExtensions[extension] = extension; + -- Register the extension as a RenderScript one. + table.insert(androidndk.sourceExtensions, extension); + androidndk.compilerFlagsVariables[extension] = "RENDERSCRIPT_FLAGS"; +end); +androidndk.asExtensions = { ".s", ".S" }; +table.foreachi(androidndk.asExtensions, function(extension) + -- Build a hash set for lookup in asExtensions. + androidndk.asExtensions[extension] = extension; + -- Register the extension as a GAS one. + table.insert(androidndk.sourceExtensions, extension); + androidndk.compilerFlagsVariables[extension] = "ASFLAGS"; +end); +-- Build a hash set for lookup in sourceExtensions. +table.foreachi(androidndk.sourceExtensions, function(extension) + androidndk.sourceExtensions[extension] = extension; +end); + +-- Define variables usable by projects for language filtering via extension filters. +-- Lowercase because it's the public interface for projects. +androidndk.filefilters = {}; +function androidndk.buildExtensionFileFilterTerms(extensions) + local extensionsCaseInsensitive = {}; + -- Premake filters are case-insensitive - don't add the same extension twice. + for i, extension in ipairs(extensions) do + table.insertkeyed(extensionsCaseInsensitive, string.lower(extension)); + end + -- Build filters including subdirectories, adding all possible ARM suffixes. + local extensionFilters = {}; + for i, extension in ipairs(extensionsCaseInsensitive) do + local extensionFilter = "**" .. extension; + table.insert(extensionFilters, extensionFilter); + table.insert(extensionFilters, extensionFilter .. ".arm"); + table.insert(extensionFilters, extensionFilter .. ".neon"); + table.insert(extensionFilters, extensionFilter .. ".arm.neon"); + end + return extensionFilters; +end +-- Initializing public helpers (and thus lowercase names) - don't remove even though they are not referenced within the module itself! +(function() + local languageFilterVariables = { + { + language = "as", + extensions = androidndk.asExtensions, + }, + { + language = "asm", + extensions = { androidndk.asmExtension }, + }, + { + language = "c", + extensions = { androidndk.cExtension }, + }, + { + language = "cpp", + -- Premake filters are case-insensitive, so C sources would pass **.C as well - skip it in the C++ filter. + -- It's not recommended to use the .C extension at all for this reason. + extensions = table.filter( + androidndk.cppExtensions, + function(extension) + return extension ~= ".C"; + end), + }, + { + language = "rs", + extensions = androidndk.rsExtensions, + }, + }; + for i, languageFilterVariable in ipairs(languageFilterVariables) do + local extensionsCaseInsensitive = {}; + -- Premake filters are case-insensitive - don't add the same extension twice. + for i2, extension in ipairs(languageFilterVariable.extensions) do + table.insertkeyed(extensionsCaseInsensitive, string.lower(extension)); + end + -- Build arrays of raw extensions with all possible ARM suffixes: + -- androidndk.prefixfilefilterextensions = { ".ext", ".ext.arm", ".ext.neon", ".ext.arm.neon"... } + -- This allows arbitrary usage of table.translate, including to prepend a specific file name. + local extensionsWithSuffixes = {}; + for i2, extension in ipairs(extensionsCaseInsensitive) do + table.insert(extensionsWithSuffixes, extension); + table.insert(extensionsWithSuffixes, extension .. ".arm"); + table.insert(extensionsWithSuffixes, extension .. ".neon"); + table.insert(extensionsWithSuffixes, extension .. ".arm.neon"); + end + androidndk.filefilters[languageFilterVariable.language .. "extensions"] = extensionsWithSuffixes; + -- Build inclusive filters for all subdirectories as a string. + -- androidndk.filefilters.language = "files:**.ext or files:**.ext.arm or files:**.ext.neon or files:**.ext.arm.neon..." + androidndk.filefilters[languageFilterVariable.language] = + table.concat( + table.translate( + extensionsWithSuffixes, + function(extension) + return "files:**" .. extension; + end), + " or "); + -- Build exclusive filters for all subdirectories as a table. + -- androidndk.filefilters.notlanguage = { "files:not **.ext", "files:not **.ext.arm", "files:not **.ext.neon", "files:not **.ext.arm.neon"... } + androidndk.filefilters["not" .. languageFilterVariable.language] = + table.translate( + extensionsWithSuffixes, + function(extension) + return "files:not **" .. extension; + end); + end +end)(); + +-- In this module, flags are gathered from both the project configuration and per-file configuration. +-- ndk-build, however, doesn't support per-file flags. +-- Per-file configuration is needed though because compilers for different languages may need different flags. +-- The `language` setting is a whole-project setting, it alone can't be used in a filter to specify which compiler should receive the flags. +-- Therefore, the file extension must be used as a filter. +-- This leads of a lot of duplication - every file in the project has project-level flags as well as extension-specific flags. +-- For this reason, each flag is added only once. +-- Because of this, a flag may contain one or multiple whitespace-separated compiler argument. +-- "-include a.h -include b.h -include \"c d.h\" -include \"c d.h\"" must NOT be deduplicated as: +-- { "-include", "a.h", "b.h", "\"c d.h\"" } +-- or as: +-- { "-include", "a.h", "b.h", "\"c", "d.h\"" } +-- It must be: +-- { "-include a.h", "-include b.h", "-include \"c d.h\"" } + +-- Built-in flags (derived from from boolean or enumeration settings) here are added to the flags table directly as p.esc(value). +-- Most shell characters in them will be escaped at build time, however, " and \ will not. +-- So, it's possible to have built-in flags corresponding to one (possibly with quoted whitespaces) or multiple (with unquoted whitespaces) compiler arguments. +-- If a double quote character or a backslash needs to be used as a raw character, it needs to be pre-escaped manually in the flag literal here. +-- GNU make variable and function references should be used in built-in flags very carefully for the same reason. +-- Ordering of the flags is preserved only for their first occurrences in each of the LOCAL_languageFLAGS. +-- In Clang, if there are conflicting flags (such as -f and -fno), the ones later in the list take precedence. +-- Per-extension flags are therefore added after project-scope flags so the former can override the latter. + +-- Makes the value a single command line arguments passed to the compiler with a prefix, which may be in the same or in a separate argument. +-- The value must be pre-escaped with p.esc. +-- The prefix (not pre-escaped) will be handled similar to built-in flags, and may contain unquoted whitespaces for separate command line arguments. +-- Examples of the output: +-- * -DCSTRING=\"Hello\" +-- * -D"CSTRING=\"Hello, world!\"" +-- * -D "YASMSTRING=\"Hello, world!\"" +-- * -include header.h +-- * -include "header file.h" +-- * PREMAKE_ANDROIDNDK_TEMPORARY_1 := $(ENVIRONMENT_VARIABLE)/New folder (2)/header file.h +-- -include "$(call PREMAKE_ANDROIDNDK_SHELL_ESCAPE_PRE_QUOTES,$(PREMAKE_ANDROIDNDK_TEMPORARY_1))" +function androidndk.getSingleArgumentPrefixedFlagPostValueEsc(value, prefix, temporaryVariables) + local flagParts = { p.esc(prefix) }; + -- While it's completely safe to add excessive quotes in general, in some cases ndk-build doesn't expect them. + -- One example being LOCAL_LDLIBS, which is designed only for linking to Android system libraries. + -- ndk-build checks each entry against a list of known Android system libraries, and throws a warning if any non-system ones are specified. + -- The intended usage pattern of LOCAL_LDLIBS `LOCAL_LDLIBS := -landroid -llog`, not ``LOCAL_LDLIBS := -l"android" -l"log"`. + -- So, adding quotes only if there are whitespaces or references (for which it's not known whether they will be expanded to something containing whitespaces). + local isQuoted = androidndk.hasNonEmptyMakeReferencesPostEsc(value) or androidndk.staticallyHasPatternPostEsc(value, "%s"); + if isQuoted then + table.insert(flagParts, "\""); + end + table.insert(flagParts, androidndk.shellEscapePreQuotesPostEsc(value, temporaryVariables)); + if isQuoted then + table.insert(flagParts, "\""); + end + return table.concat(flagParts); +end + +-- System include directories are normally placed after the local ones, including in ndk-build itself. +androidndk.includeDirsConfigSettings = { "includedirs", "sysincludedirs" }; + +function androidndk.addIncludeDirs(includeDirs, config) + -- In LOCAL_C_INCLUDES (tested on it, but LOCAL_RENDERSCRIPT_INCLUDES goes to the host-c-includes call too): + -- Allowed directly on Linux: !%*+,-./:=?@[]^_{}~ + -- Allowed if \-escaped on Linux: "&'();<>\`| + -- Escaped UNC paths (beginning with \\\\) are supported on Windows. + -- Disallowed: whitespaces, #$ + -- In the NDK itself, either absolute or relative to the NDK root, not to the local path - need $(LOCAL_PATH) explicitly. + for i, settingName in ipairs(androidndk.includeDirsConfigSettings) do + local settingOutput = includeDirs[settingName]; + if settingOutput == nil then + settingOutput = {}; + includeDirs[settingName] = settingOutput; + end + local settingInput = config[settingName]; + for i2, includeDir in ipairs(settingInput) do + local includeDirPath = androidndk.getEscapedProjectRelativePath(config.project, includeDir, true); + if androidndk.staticallyHasPatternPostEsc(includeDirPath, "[%s#%$]") then + p.warn( + "Skipping workspace '%s' project '%s' configuration '%s' include directory '%s' with whitespaces or disallowed characters #$", + config.workspace.name, config.project.name, config.name, includeDir); + else + table.insert(settingOutput, includeDirPath); + end + end + end +end + +function androidndk.writeProjectIncludeDirs(includeDirsForAllVariables, variable, escapeShellCharacters) + local includeDirsForVariable = includeDirsForAllVariables[variable]; + if includeDirsForVariable == nil then + return false; + end + -- Merge all config settings the include directories are gathered from in the correct order. + local includeDirsForVariableMerged = {}; + for i, configSettingName in ipairs(androidndk.includeDirsConfigSettings) do + if includeDirsForVariable[configSettingName] ~= nil then + for i2, includeDir in ipairs(includeDirsForVariable[configSettingName]) do + table.insertkeyed(includeDirsForVariableMerged, includeDir); + end + end + end + local localVariable = "LOCAL_" .. variable; + if androidndk.assignToVariablePostEsc(localVariable, includeDirsForVariableMerged, true, androidndk.shellEscapeChecker) then + if escapeShellCharacters then + androidndk.writePostProcessCall(localVariable, androidndk.shellEscapeMakeCall); + end + return true; + end + return false; +end + +-- Assuming Clang - GCC was removed in NDK r13. +-- RenderScript is based on C99, but for writing compute kernels. + +-- Supported values are built-in flags as single strings and tables of strings (will be separate flags table elements). + +androidndk.asmFlagsSettingFlags = { + { key = "FatalCompileWarnings", value = "-Werror" }, +}; + +androidndk.cCppFlagsSettingFlags = { + { key = "FatalCompileWarnings", value = "-Werror" }, + -- LinkTimeOptimization is per-project, not per-extension, as it needs to be easily queryable in static library dependency analysis. + -- NoBufferSecurityCheck is C++-only in p.clang, but nothing precludes its usage in C. + -- Android uses -fstack-protector-strong by default as of NDK r23. + { key = "NoBufferSecurityCheck", value = "-fno-stack-protector" }, + { key = "ShadowedVariables", value = "-Wshadow" }, + { key = "UndefinedIdentifiers", value = "-Wundef" }, +}; + +androidndk.rsFlagsSettingFlags = { + { key = "FatalCompileWarnings", value = "-Werror" }, + { key = "ShadowedVariables", value = "-Wshadow" }, + { key = "UndefinedIdentifiers", value = "-Wundef" }, +}; + +-- Instead of using p.clang and mapFlags (with all its complexity), listing only what's relevant to ndk-build. +-- Supported keys are only strings and booleans (as p.OFF and p.ON), no tables (to avoid the complexity of keeping a deterministic order). +-- Supported values are built-in flags as single strings and tables of strings (will be separate flags table elements). +-- Values may contain unquoted (for multiple options) or quoted whitespaces, or \-escaped " and \, but p.esc will be done before writing. + +androidndk.asmSettingValueFlags = { + { + key = "warnings", + values = { + [p.OFF] = "-w", + }, + }, +}; + +androidndk.cCppSettingValueFlags = { + -- architecture is chosen via APP_ABI. + -- flags are handled separately to avoid ensuring deterministic table ordering. + { + key = "floatingpoint", + values = { + Fast = "-ffast-math", + }, + }, + -- floatingpointexceptions not present in p.clang as of v5.0.0-alpha16, added here. + { + key = "floatingpointexceptions", + values = { + [p.ON] = "-ftrapping-math", + [p.OFF] = "-fno-trapping-math", + }, + }, + { + key = "strictaliasing", + values = { + [p.OFF] = "-fno-strict-aliasing", + Level1 = { "-fstrict-aliasing", "-Wstrict-aliasing=1" }, + Level2 = { "-fstrict-aliasing", "-Wstrict-aliasing=2" }, + Level3 = { "-fstrict-aliasing", "-Wstrict-aliasing=3" }, + }, + }, + -- optimize is chosen via APP_OPTIM. + -- pic is always enabled by ndk-build and is required on Android. + -- vectorextensions are per-architecture. + -- isaextensions are per-architecture. + { + key = "warnings", + values = { + [p.OFF] = "-w", + High = "-Wall", + Extra = { "-Wall", "-Wextra" }, + Everything = "-Weverything", + }, + }, + -- symbols are chosen via APP_DEBUG. + { + key = "unsignedchar", + values = { + [p.ON] = "-funsigned-char", + [p.OFF] = "-fno-unsigned-char", + }, + }, + -- omitframepointer Off is needed for the Address Sanitizer, so exposed here. + -- More info about omitframepointer on Android: https://github.com/android/ndk/issues/824 + { + key = "omitframepointer", + values = { + [p.ON] = "-fomit-frame-pointer", + [p.OFF] = "-fno-omit-frame-pointer", + }, + }, + -- visibility and inlinesvisibility are C++-only in p.clang in v5.0.0-alpha16, but nothing precludes their usage in C. + { + key = "visibility", + values = { + Default = "-fvisibility=default", + Hidden = "-fvisibility=hidden", + Internal = "-fvisibility=internal", + Protected = "-fvisibility=protected", + }, + }, + { + key = "inlinesvisibility", + values = { + Hidden = "-fvisibility-inlines-hidden", + }, + }, +}; + +androidndk.cSettingValueFlags = { + { + key = "cdialect", + values = { + ["C89"] = "-std=c89", + ["C90"] = "-std=c90", + ["C99"] = "-std=c99", + ["C11"] = "-std=c11", + ["gnu89"] = "-std=gnu89", + ["gnu90"] = "-std=gnu90", + ["gnu99"] = "-std=gnu99", + ["gnu11"] = "-std=gnu11", + }, + }, +} + +androidndk.cppSettingValueFlags = { + -- exceptionhandling is chosen via LOCAL_CPP_FEATURES. + { + key = "cppdialect", + values = { + ["C++98"] = "-std=c++98", + ["C++0x"] = "-std=c++0x", + ["C++11"] = "-std=c++11", + ["C++1y"] = "-std=c++1y", + ["C++14"] = "-std=c++14", + ["C++1z"] = "-std=c++1z", + ["C++17"] = "-std=c++17", + ["C++2a"] = "-std=c++2a", + ["C++20"] = "-std=c++20", + ["gnu++98"] = "-std=gnu++98", + ["gnu++0x"] = "-std=gnu++0x", + ["gnu++11"] = "-std=gnu++11", + ["gnu++1y"] = "-std=gnu++1y", + ["gnu++14"] = "-std=gnu++14", + ["gnu++1z"] = "-std=gnu++1z", + ["gnu++17"] = "-std=gnu++17", + ["gnu++2a"] = "-std=gnu++2a", + ["gnu++20"] = "-std=gnu++20", + ["C++latest"] = "-std=c++20", + }, + }, + -- rtti is chosen via LOCAL_CPP_FEATURES. +}; + +androidndk.rsSettingValueFlags = { + { + key = "warnings", + values = { + [p.OFF] = "-w", + High = "-Wall", + Extra = { "-Wall", "-Wextra" }, + Everything = "-Weverything", + }, + }, + -- No other cCppFlagsSettingFlags and cSettingValueFlags are supported. +}; + +androidndk.asmWarningFlags = { + { key = "enablewarnings", prefix = "-W" }, + { key = "disablewarnings", prefix = "-Wno-" }, + -- No -Werror= on YASM, pick the closest to the intention. + { key = "fatalwarnings", prefix = "-W" }, +}; + +androidndk.cCppWarningFlags = { + { key = "enablewarnings", prefix = "-W" }, + { key = "disablewarnings", prefix = "-Wno-" }, + { key = "fatalwarnings", prefix = "-Werror=" }, +}; + +function androidndk.addCompilerFlagsForExtension(flagsForExtension, extension, config, temporaryVariables) + -- Make sure the table for generic flags exists. + if flagsForExtension.buildoptions == nil then + flagsForExtension.buildoptions = {}; + end + + local isCCpp = extension == androidndk.cExtension or androidndk.cppExtensions[extension] ~= nil; + + local languageDefinesPrefix = nil; + local languageUndefinesPrefix = nil; + local languageFlagsSettingFlags = nil; + local languageSettingValueFlagsTables = {}; + local languageWarningFlags = nil; + if extension == androidndk.asmExtension then + -- The defines prefix is separated into a different argument. + languageDefinesPrefix = "-D "; + languageUndefinesPrefix = "-U "; + languageFlagsSettingFlags = androidndk.asmFlagsSettingFlags; + table.insert(languageSettingValueFlagsTables, androidndk.asmSettingValueFlags); + languageWarningFlags = androidndk.asmWarningFlags; + elseif isCCpp then + -- The defines prefix is in the same argument (though separation also works, but ndk-build itself doesn't separate). + languageDefinesPrefix = "-D"; + languageUndefinesPrefix = "-U"; + -- Currently only shared between C and C++. + languageFlagsSettingFlags = androidndk.cCppFlagsSettingFlags; + table.insert(languageSettingValueFlagsTables, androidndk.cCppSettingValueFlags); + if androidndk.cppExtensions[extension] ~= nil then + table.insert(languageSettingValueFlagsTables, androidndk.cppSettingValueFlags); + else + table.insert(languageSettingValueFlagsTables, androidndk.cSettingValueFlags); + end + languageWarningFlags = androidndk.cCppWarningFlags; + elseif androidndk.rsExtensions[extension] ~= nil then + -- -D and -U are not supported. + languageFlagsSettingFlags = androidndk.rsFlagsSettingFlags; + table.insert(languageSettingValueFlagsTables, androidndk.rsSettingValueFlags); + languageWarningFlags = androidndk.cCppWarningFlags; + end + + -- Preprocessor definitions (not supported by the GNU assembler). + -- Potentially with whitespaces, but need to go to a single (quoted) argument. + -- Defines before undefines for consistency with other Premake actions such as Visual Studio. + -- Placing them in separate tables so they're not mixed if both defines are undefines are provided by both the project and the extension filter. + -- Not doing the same for -D and -U provided via raw buildoptions though to avoid interfering with the project-provided order. + if languageDefinesPrefix ~= nil then + if flagsForExtension.defines == nil then + flagsForExtension.defines = {}; + end + for i, define in ipairs(config.defines) do + table.insertkeyed( + flagsForExtension.defines, + androidndk.getSingleArgumentPrefixedFlagPostValueEsc(p.esc(define), languageDefinesPrefix, temporaryVariables)); + end + end + if languageUndefinesPrefix ~= nil then + if flagsForExtension.undefines == nil then + flagsForExtension.undefines = {}; + end + for i, undefine in ipairs(config.undefines) do + table.insertkeyed( + flagsForExtension.undefines, + androidndk.getSingleArgumentPrefixedFlagPostValueEsc(p.esc(undefine), languageUndefinesPrefix, temporaryVariables)); + end + end + + -- Forced include paths (not supported by the GNU assembler). + if extension == androidndk.asmExtension then + for i, forceInclude in ipairs(config.forceincludes) do + local forceIncludePath = androidndk.getEscapedProjectRelativePath(config.project, forceInclude, true); + if androidndk.staticallyHasPatternPostEsc(forceIncludePath, "[\"';]") then + p.warn( + "Skipping workspace '%s' project '%s' configuration '%s' Yasm force include '%s' with path containing disallowed characters \"';", + config.workspace.name, config.project.name, config.name, forceInclude); + else + table.insertkeyed( + flagsForExtension.buildoptions, + androidndk.getSingleArgumentPrefixedFlagPostValueEsc(forceIncludePath, "-P ", temporaryVariables)); + end + end + elseif isCCpp then + -- -include is not supported by RenderScript. + for i, forceInclude in ipairs(config.forceincludes) do + local forceIncludePath = androidndk.getEscapedProjectRelativePath(config.project, forceInclude, true); + -- -include %s becomes #include "%s", the inner " is considered a string terminator. + if androidndk.staticallyHasPatternPostEsc(forceIncludePath, "[\"]") then + p.warn( + "Skipping workspace '%s' project '%s' configuration '%s' C/C++ force include '%s' with path containing a disallowed double quote character", + config.workspace.name, config.project.name, config.name, forceInclude); + else + table.insertkeyed( + flagsForExtension.buildoptions, + androidndk.getSingleArgumentPrefixedFlagPostValueEsc(forceIncludePath, "-include ", temporaryVariables)); + end + end + end + + -- Flags for configuration flags setting. + if languageFlagsSettingFlags ~= nil then + for i, flagsSettingKeyValue in ipairs(languageFlagsSettingFlags) do + if config.flags[flagsSettingKeyValue.key] then + local flagsSettingValue = flagsSettingKeyValue.value; + if type(flagsSettingValue) ~= "table" then + flagsSettingValue = { flagsSettingValue }; + end + for i2, flagsSettingValueBuildOption in ipairs(flagsSettingValue) do + table.insertkeyed(flagsForExtension.buildoptions, p.esc(flagsSettingValueBuildOption)); + end + end + end + end + + -- Flags for setting values. + for i, languageSettingValueFlags in ipairs(languageSettingValueFlagsTables) do + for i2, languageSettingValueKeyValues in ipairs(languageSettingValueFlags) do + local settingValue = config[languageSettingValueKeyValues.key]; + if settingValue ~= nil then + -- Convert boolean to off/on. + if settingValue == false then + settingValue = p.OFF; + elseif settingValue == true then + settingValue = p.ON; + end + local settingValueFlags = languageSettingValueKeyValues.values[settingValue]; + if settingValueFlags ~= nil then + if type(settingValueFlags) ~= "table" then + settingValueFlags = { settingValueFlags }; + end + for i3, settingValueFlag in ipairs(settingValueFlags) do + table.insertkeyed(flagsForExtension.buildoptions, p.esc(settingValueFlag)); + end + end + end + end + end + + -- Individual warnings. + -- After generic setting flags which include the default warning behavior so -Wname can override -w. + if languageWarningFlags ~= nil then + for i, warningKeyPrefix in ipairs(languageWarningFlags) do + for i2, warning in ipairs(config[warningKeyPrefix.key]) do + table.insertkeyed( + flagsForExtension.buildoptions, + androidndk.getSingleArgumentPrefixedFlagPostValueEsc(p.esc(warning), warningKeyPrefix.prefix, temporaryVariables)); + end + end + end + + -- Add raw project-specified flags, as single or multiple arguments, after everything (so they can cancel internal flags). + -- Quoting, or escaping of quotes, must be done by the project instead, as a single build option may contain multiple arguments. + -- Build options are platform-dependent anyway - the module is free to establish any rules. + for i, buildOption in ipairs(config.buildoptions) do + local buildOptionEscaped = p.esc(buildOption); + table.insertkeyed(flagsForExtension.buildoptions, buildOptionEscaped); + if isCCpp and androidndk.isFltoOption(buildOptionEscaped) then + -- Store the last (thus the highest-priority) -flto type used by the language. + -- RenderScript doesn't support -flto. + flagsForExtension.flto = buildOptionEscaped; + end + end +end + +-- Defines before undefines for consistency with other Premake actions such as Visual Studio. +-- Everything special before everything generic (including raw project buildoptions) for the same reason. +-- Separate to make sure -D -U -D -U instead of -D -D -U -U doesn't happen if both are provided by both the project and the extension filter. +androidndk.projectCompilerFlagsOrder = { "defines", "undefines", "buildoptions" }; + +function androidndk.writeProjectCompilerFlags(flagsForAllVariables, variable, escapeShellCharacters) + local flagsForVariable = flagsForAllVariables[variable]; + if flagsForVariable == nil then + return false; + end + local flagsForVariableMerged = {}; + -- Merge all sources of flags in the correct order. + for i, flagsTableName in ipairs(androidndk.projectCompilerFlagsOrder) do + if flagsForVariable[flagsTableName] ~= nil then + for i2, flag in ipairs(flagsForVariable[flagsTableName]) do + table.insertkeyed(flagsForVariableMerged, flag); + end + end + end + local localVariable = "LOCAL_" .. variable; + if androidndk.assignToVariablePostEsc(localVariable, flagsForVariableMerged, true, androidndk.shellEscapePostQuotesChecker) then + if escapeShellCharacters then + androidndk.writePostProcessCall(localVariable, androidndk.shellEscapePostQuotesMakeCall); + end + return true; + end + return false; +end + +-- Built-in flags for ISA and vector extensions. + +androidndk.abiIsaExtensions = { + ["x86"] = { + MOVBE = "-mmovbe", + POPCNT = "-mpopcnt", + PCLMUL = "-mpclmul", + LZCNT = "-mlzcnt", + BMI = "-mbmi", + BMI2 = "-mbmi2", + F16C = "-mf16c", + AES = "-maes", + FMA = "-mfma", + FMA4 = "-mfma4", + RDRND = "-mrdrnd", + }, +}; +androidndk.abiIsaExtensions["x86_64"] = androidndk.abiIsaExtensions["x86"]; + +androidndk.abiVectorExtensions = { + ["x86"] = { + -- Up to SSSE3 are required. + ["SSE4.1"] = "-msse4.1", + ["SSE4.2"] = "-msse4.2", + ["AVX"] = "-mavx", + ["AVX2"] = "-mavx2", + }, + ["x86_64"] = { + -- Up to SSE4.2 are required. + ["AVX"] = "-mavx", + ["AVX2"] = "-mavx2", + }, +}; + +-- Escaped or not doesn't matter. +function androidndk.isFltoOption(option) + -- Remove quotes (so "-flto..." is handled like -flto...). + -- Escaped or not doesn't matter as the pattern being checked doesn't include a backslash. + option = string.gsub(option, "\"", ""); + -- Let -flto alone, or -flto=..., pass. + return string.find(option, "^%s*%-flto%s$") ~= nil or string.find(option, "^%s*%-flto=") ~= nil; +end + +-- ldFlagsUndefined receives -u and --undefined from `linkoptions`. +-- ldLibsDirFlags receives -L from `linkoptions` and -L for `links`. +-- ldLibsSysDirFlags receives -L for `syslibdirs`. +-- ldLibsLibFlags receives -l from `linkoptions` and -l for `links`. +-- ldFlags receives the rest of `linkoptions`. +-- Any output table can be nil. +-- In this case, only libraries to link to will be obtained and written to ldLibs*Flags. +-- Returns the last encountered (thus highest-priority) -flto option if any is passed (so non-default LTO types can be used with transitivity). +function androidndk.addSingleConfigLinkerFlags(config, ldFlagsUndefined, ldFlags, ldLibsDirFlags, ldLibsSysDirFlags, ldLibsLibFlags, temporaryVariables) + -- NDK passes LDFLAGS before LDLIBS. + -- It also placed local LDLIBS before imported LDLIBS. + -- Entries for the system libraries (`syslibdirs` here specifically) should be the last according to this ordering also. + -- The system can be considered the deepest import of everything. + -- For LDFLAGS, it's the reverse, however - imported LDFLAGS are before local LDFLAGS. + + -- This module also distributes `linkoptions` between LDFLAGS and LDLIBS instead of passing all to LDFLAGS. + -- LDLIBS is what's designed to hold the -l flags for the system libraries to link to. + -- While LDFLAGS can contain -l too, it's not the intended way of passing them. + -- The reason why this is taken into consideration, and `linkoptions` are parsed at all, is the special case of name collision resolution. + -- A workspace may contain its own project, for example, named "log", and in this case a "log" link would be considered a sibling link, not a system one. + -- An alternative would be to link to ":liblog.so". + -- However, this will result in a warning as ndk-build uses simpler logic for checking whether only system libraries are specified which fails for that. + -- Therefore, this module offers a way to pass "-llog" via `linkoptions`. + + -- Normally though -l should be used only for a small fixed set of Android NDK system libraries. + -- All this logic is therefore a massive overkill. + -- Prebuilt library projects normally should be used instead of -L and -l. + -- However, for the ease of porting, and to avoid adding constraints, letting projects link directly to libraries via raw linker arguments anyway. + -- Specifying anything but -l would throw a warning though. + + -- Search paths (-L) apply to all -l options regardless of the order. + -- They can be written to either LDFLAGS or LDLIBS. + -- This module implements dependency transitivity a custom way, stopping iterating at shared libraries (unlike NDK's internal exports). + -- For this purpose, it only imports everything that goes to LDLIBS, but not to LDFLAGS - assuming it contains everything needed for library linkage. + -- So, always writing search paths to LDLIBS here, not to LDFLAGS. + + -- Handling `linkoptions` before `links` and `syslibdirs` because the latter is conceptually closer to LDFLAGS, and the latter two to LDLIBS. + -- Considering -L specified in `linkoptions` as the more generic `links` (which are placed before `syslibdirs`) for the same reason as well. + + local flto = nil; + local longLinkOptions = { + { + name = "--library", + destination = ldLibsLibFlags, + }, + { + name = "--library-path", + destination = ldLibsDirFlags, + }, + { + name = "--undefined", + destination = ldFlagsUndefined, + }, + }; + for i, linkOptionUnescaped in ipairs(config.linkoptions) do + local linkOption = p.esc(linkOptionUnescaped); + -- Check which output table should receive the option. + local linkOptionDestination = ldFlags; + -- -flto is a Clang++ option, not an LLD one - don't check it if there's -Wl. + -- Also, it's either a full option, or an option with a value - check it in a special way for this reason as well. + if androidndk.isFltoOption(linkOption) then + flto = linkOption; + else + -- Trim whitespaces (until the first quote if present). + local linkOptionFirstNonWhitespace = string.find(linkOption, "[%S]"); + if linkOptionFirstNonWhitespace ~= nil then + -- Remove quotes (so "-l..." is handled like -l...). + -- Escaped or not doesn't matter as none of the checked prefixes include a backslash. + local linkOptionForPrefix = string.gsub(string.sub(linkOption, linkOptionFirstNonWhitespace, -1), "\"", ""); + -- ndk-build passes the flags to Clang++, not to LLD directly. + -- Therefore, most of linker options must be passed via -Wl, and for those that don't, the presence of -Wl doesn't matter. + -- Specifically, -l and -L can be passed to both Clang++ and LLD, but --library and --library-path can't (and require -Wl). + -- -l and -L can be either attached directly to the name or placed in a separate (whitespace-separated) argument. + -- --library and --library-path can be either attached with a = or placed in a separate argument. + -- Since --library and --library-path require -Wl, arguments are comma-separate rather than whitespace-separated. + local wlPrefix = "-Wl,"; + local wlPrefixLength = string.len(wlPrefix); + local hasWl = string.sub(linkOption, 1, string.len(wlPrefixLength)) == wlPrefix; + if hasWl then + linkOptionForPrefix = string.sub(linkOptionForPrefix, wlPrefixLength + 1, -1); + end + local linkOptionSingleCharacterPrefix = string.sub(linkOptionForPrefix, 1, 2); + if linkOptionSingleCharacterPrefix == "-u" then + linkOptionDestination = ldFlagsUndefined; + elseif linkOptionSingleCharacterPrefix == "-l" then + linkOptionDestination = ldLibsLibFlags; + elseif linkOptionSingleCharacterPrefix == "-L" then + linkOptionDestination = ldLibsDirFlags; + else + if hasWl then + -- Check if --Wl,--option=value or --Wl,--option,value is used. + for i2, longLinkOption in ipairs(longLinkOptions) do + local longLinkOptionPrefixSub = string.sub(linkOptionForPrefix, 1, string.len(longLinkOption.name)); + if longLinkOption.name == (longLinkOptionPrefixSub .. "=") or longLinkOption.name == (longLinkOptionPrefixSub .. ",") then + linkOptionDestination = longLinkOption.destination; + break; + end + end + end + end + end + end + -- Add the flag to the needed table if adding to one was requested at all. + -- Quoting, or escaping of quotes, must be done by the project instead, as a single link option may contain multiple arguments. + -- Link options are platform-dependent anyway - the module is free to establish any rules. + if linkOptionDestination ~= nil then + table.insertkeyed(linkOptionDestination, linkOption); + end + end + + -- Local search paths (`libdirs` and `links`). + if ldLibsDirFlags ~= nil then + for i, libDir in ipairs(p.config.getlinks(config, "system", "directory")) do + local libDirRelativePath = androidndk.getEscapedProjectRelativePath(config.project, libDir, true); + table.insertkeyed( + ldLibsDirFlags, + androidndk.getSingleArgumentPrefixedFlagPostValueEsc(libDirRelativePath, "-L", temporaryVariables)); + end + end + + -- System search paths. + if ldLibsSysDirFlags ~= nil then + for i, sysLibDir in ipairs(config.syslibdirs) do + local sysLibDirRelativePath = androidndk.getEscapedProjectRelativePath(config.project, sysLibDir, true); + table.insertkeyed( + ldLibsSysDirFlags, + androidndk.getSingleArgumentPrefixedFlagPostValueEsc(sysLibDirRelativePath, "-L", temporaryVariables)); + end + end + + -- Local links. + -- Specifying the : prefix directly in `links` is allowed to force treatment of the name as a full file name instead of a short name. + -- However, just specifying the full file name is also allowed for simplicity of the usage (especially of the usage of full paths). + -- libname.so will be treated as libname.so, not as liblibname.so.a or liblibname.so.so. + -- However, something like name.thumb will be treated as libname.thumb.a/libname.thumb.so still. + -- Making no special assumptions about GNU make references (such as environment variables). + -- The intended usage of LOCAL_LDLIBS is purely for linking to the libraries provided by the Android NDK via their short names anyway. + -- To use, for instance, a full path from an environment variable (or a different kind of a GNU make reference), specify: + -- links({ "$(dir $(VARIABLE))/:$(notdir $(VARIABLE))" }) + if ldLibsLibFlags ~= nil then + for i, libName in ipairs(p.config.getlinks(config, "system", "name")) do + local libNamePrefix = ""; + if string.sub(libName, 1, 1) ~= ":" then + -- Full name not forced. + -- Check if using the full name anyway. + local libExtension = path.getextension(libName); + if libExtension == ".a" or libExtension == ".so" then + libNamePrefix = ":"; + end + end + table.insertkeyed( + ldLibsLibFlags, + androidndk.getSingleArgumentPrefixedFlagPostValueEsc(p.esc(libNamePrefix .. libName), "-l", temporaryVariables)); + end + end + + return flto; +end + +function androidndk.generateProjectConfig(config) + local temporaryVariables = {}; + + local configAbi = androidndk.getConfigAbi(config); + assert(configAbi ~= nil, "Configurations with invalid ABIs must be skipped in isConfigSupported"); + + local configUsesA32 = androidndk.configUsesA32(config); + local configUsesNeon = androidndk.configUsesNeon(config); + + -- Get the precompiler header path. + -- Handling of the ARM instruction set and NEON is done by ndk-build implicitly, not possible and not needed to specify suffixes. + -- All the inclusion of the built header is done by ndk-build itself implicitly. + -- At this point, it's needed for getting the file configuration for it so, if needed, C++-specific options can be extracted from it. + local pch = nil; + if not config.flags.NoPCH and config.pchheader ~= nil then + pch = androidndk.getEscapedProjectRelativePath(config.project, config.pchheader, false); + -- LOCAL_PCH is involved a value that goes to LOCAL_SRC_FILES internally in ndk-build, so the rules are the same. + -- However, = is also not allowed. + if androidndk.staticallyHasPatternPostEsc(pch, "[%s\"#%$&'%(%),;<=>`|]") then + p.warn( + "Skipping workspace '%s' project '%s' configuration '%s' precompiled header '%s' " .. + "with path containing whitespaces or disallowed characters \"#$&'(),;<=>`|", + config.workspace.name, config.project.name, config.name, pch); + pch = nil; + end + end + local pchFileConfig = nil; + + -- Gather source files not excluded from build. + local sourceTree = p.project.getsourcetree(config.project); + local configAbiSupportsYasm = configAbi == "x86" or configAbi == "x86_64" or configAbi == androidndk.ABI_ALL; + -- External Android.mk files and prebuilt libraries. + local sourcePrecreatedFiles = {}; + -- Keys - sequential indexes, paths without .arm and .neon suffixes. + -- Values - paths with .arm and .neon suffixes. + local sourceFiles = {}; + local sourceFilesYasmConditional = {}; + -- includeDirs[variable] and compilerFlags[variable] may be nil if no source files contributing to them have been found yet. + -- Each includeDirs element optionally contains includedirs = {}, sysincludedirs = {}. + local includeDirs = {}; + local renderScriptIncludeDirsVariable = iif(config.renderscriptincludedirsoverride == true, "RENDERSCRIPT_INCLUDES_OVERRIDE", "RENDERSCRIPT_INCLUDES"); + -- Each compilerFlags element optionally contains defines = {}, undefines = {}, buildoptions (used for the rest of flags) = {}, flto = "...". + -- flto, if present, contains the last -flto flag encountered for this extension. + local compilerFlags = {}; + -- For simplicity, for project-defined flags, using separate CONLYFLAGS and CPPFLAGS. + -- Using LOCAL_CFLAGS is also undesirable because they go not only to C and C++, but to GNU assembly as well. + -- See the definition of ev-compile-s-source in ndk-build. + local configIncludeDirsAdded = {}; + local configCompilerFlagsAdded = {}; + p.tree.traverse(sourceTree, { + onleaf = function(fileNode, depth) + local fileConfig = p.fileconfig.getconfig(fileNode, config); + -- Check if the file is present at all in the current configuration and not explicitly excluded with a file filter. + if fileConfig ~= nil then + -- abspath must be used, as with relpath or path, a path relative to the Android.mk location is written in the end, not to LOCAL_PATH. + local sourceOriginalRelativePath = androidndk.getEscapedProjectRelativePath(config.project, fileNode.abspath, false); + -- If this is the precompiled header, store the file configuration for it so it can be used later to obtain C++-specific settings. + -- ExcludeFromBuild has no effect on whether the precompiled header is used in other Premake actions. + if sourceOriginalRelativePath == pch then + pchFileConfig = fileConfig; + end + if not fileConfig.flags.ExcludeFromBuild then + -- Handle according to the extension. + -- Supporting external Android.mk files, prebuilt libraries, source files (possibly with .arm and .neon suffixes). + -- Unlike path.hasextension, ndk-build is case-sensitive (.C is treated as C++ by ndk-build by default). + -- Therefore, using == for path.getextension instead of path.hasextension as the latter is case-insensitive. + local sourceOriginalExtension = path.getextension(sourceOriginalRelativePath); + local sourceOriginalBaseName = path.getbasename(sourceOriginalRelativePath); + -- Check if the file name is not empty. + if sourceOriginalBaseName ~= "" then + if sourceOriginalExtension == ".mk" then + -- Need the full path, not a relative path like in LOCAL_SRC_FILES. + local sourceAndroidMkPath = androidndk.getEscapedProjectRelativePath(config.project, fileNode.abspath, true); + -- Whitespaces in include statements are supported, but need to be escaped with \ which themselves are escapable in this case. + -- Meaning, n/2 backslashes will be passed, and escaping will be done only by an odd number of backslashes. + -- This makes it hard to handle cases of backslashes before whitespaces in the original path. + -- Backslashes not before spaces are treated as raw characters, however - can't replace all with two backslashes. + if androidndk.staticallyHasPatternPostEsc(sourceAndroidMkPath, "[%s]") then + p.warn( + "Skipping workspace '%s' project '%s' configuration '%s' file '%s' " .. + "with path containing whitespaces, which are not supported", + config.workspace.name, config.project.name, config.name, sourceAndroidMkPath); + else + table.insertkeyed(sourcePrecreatedFiles, sourceAndroidMkPath); + end + elseif sourceOriginalExtension == ".a" or sourceOriginalExtension == ".so" then + -- LOCAL_SRC_FILES limitations for prebuilt libraries: + -- Backslash escaping of shell characters is NOT supported on Windows. + -- Escaping with a backslash works on Linux, however, but it's not needed for any of the allowed characters there. + -- On Linux, the path goes to `cp`. + -- Disallowed characters on Linux: whitespaces, "#$%&'()*:;<>?\`| + -- * is treated as a wildcard, so it can't truly be a part of a file name either. + -- \ is allowed on Windows, however, as a path separator. + -- On Windows, the path goes to `copy` after replacing / with \. + -- Disallowed characters on Windows: whitespaces, "#$%&*;<>?| + -- : is allowed on Windows as a drive letter separator. + -- Therefore, on Windows, strictly more different characters are allowed. + -- The user may, however, possibly want to use the generated scripts on just Windows. + -- For this reason, only paths with characters disallowed on both (not either) hosts must be filtered out here. + -- There's no need to impose overly strict constraints, this check acts as a portability aid. + if androidndk.staticallyHasPatternPostEsc(sourceOriginalRelativePath, "[%s\"#%$%%&%*;<>%?|]") then + -- % needs to be escaped as %% in printf format strings. + p.warn( + "Skipping workspace '%s' project '%s' configuration '%s' file '%s' " .. + "with path containing whitespaces or disallowed characters \"#$%%&*;<>?|", + config.workspace.name, config.project.name, config.name, sourceOriginalRelativePath); + else + table.insertkeyed(sourcePrecreatedFiles, sourceOriginalRelativePath); + end + else + -- .arm and .neon suffixes internally enable the A32 instruction set and NEON respectively for the base file. + -- They're also supported on ABIs other than armeabi-v7a, having no effect in this case, the file is built as usual. + -- With LOCAL_ARM_MODE := arm and LOCAL_ARM_NEON := true respectively, they have no effect also. + -- These suffixes are allowed for all types of source files, even x86 assembly. + local sourceRelativePath = sourceOriginalRelativePath; + local sourceExtension = sourceOriginalExtension; + -- Only .arm, .neon and .arm.neon combinations are supported - not .neon.arm. + local sourceHasNeonForced = sourceExtension == ".neon"; + if sourceHasNeonForced then + sourceRelativePath = path.removeextension(sourceRelativePath); + sourceExtension = path.getextension(sourceRelativePath); + end + local sourceHasA32Forced = sourceExtension == ".arm"; + if sourceHasA32Forced then + sourceRelativePath = path.removeextension(sourceRelativePath); + sourceExtension = path.getextension(sourceRelativePath); + end + if sourceExtension == ".arm" or sourceExtension == ".neon" then + p.warn( + "Workspace '%s' project '%s' config '%s' file '%s' has an incorrect armeabi suffix - " .. + "only .arm, .neon and .arm.neon are allowed by the NDK", + config.workspace.name, config.project.name, config.name, fileNode.abspath); + else + local sourceBaseName = path.getbasename(sourceRelativePath); + -- Check if the file name is not empty. + if sourceBaseName ~= "" then + -- Silently skipping files in the project unrelated to ndk-build, as well as headers. + if androidndk.sourceExtensions[sourceExtension] ~= nil then + -- Is a source file. + + -- LOCAL_SRC_FILES limitations for source files: + -- Allowed directly on Linux: !%+-./=?@[]^_{}~ + -- Allowed if \-escaped on Linux: * + -- (* works correctly on Linux, not as a wildcard.) + -- : is allowed if escaped on Linux, but is the drive separator on Windows, and is not escapable there. + -- Absolute paths are okay, so escaping should be disabled dynamically on Windows. + -- Allowed and escapable on Windows, disallowed on Linux: \ + -- UNC paths are not supported on Windows. + -- Disallowed: whitespaces, "#$&'(),;<>`| + if androidndk.staticallyHasPatternPostEsc(sourceOriginalRelativePath, "[%s\"#%$&'%(%),;<>`|]") then + p.warn( + "Skipping workspace '%s' project '%s' configuration '%s' file '%s' " .. + "with path containing whitespaces or disallowed characters \"#$&'(),;<>`|", + config.workspace.name, config.project.name, config.name, sourceOriginalRelativePath); + else + -- Try adding the file to source files. + local sourceFileTable = sourceFiles; + if sourceExtension == androidndk.asmExtension then + -- .asm (YASM) files can be assembled only for x86 and x86_64, giving warnings on other architectures. + -- YASM files are explicitly added only for x86 and x86_64 as otherwise ndk-build will be throwing warnings. + if configAbiSupportsYasm then + if configAbi == androidndk.ABI_ALL then + -- Add YASM sources conditionally for multi-ABI configurations. + sourceFileTable = sourceFilesYasmConditional; + else + -- Add YASM sources directly to the main LOCAL_SRC_FILES assignment for x86 and x86_64. + sourceFileTable = sourceFiles; + end + else + sourceFileTable = nil; + end + end + if sourceFileTable ~= nil and sourceFileTable[sourceRelativePath] == nil then + -- New source file. + + -- Add the file to the table. + -- Allowing A32 and NEON to be enabled for files using either the suffixes or file filters. + -- Considering the suffixes more important as they're always specified for individual files, while filters can be less granular. + local sourceRelativePathWithSuffixesParts = { sourceRelativePath }; + if not configUsesA32 and not sourceHasA32Forced then + sourceHasA32Forced = androidndk.configUsesA32(fileConfig); + end + if sourceHasA32Forced then + table.insert(sourceRelativePathWithSuffixesParts, ".arm"); + end + if not configUsesNeon and not sourceHasNeonForced then + sourceHasNeonForced = androidndk.configUsesNeon(fileConfig); + end + if sourceHasNeonForced then + table.insert(sourceRelativePathWithSuffixesParts, ".neon"); + end + local sourceRelativePathWithSuffixes = table.concat(sourceRelativePathWithSuffixesParts); + sourceFileTable[sourceRelativePath] = sourceRelativePathWithSuffixes; + table.insert(sourceFileTable, sourceRelativePathWithSuffixes); + + -- Gather include directories. + -- C_INCLUDES is used for C, C++, GAS and YASM (all non-RenderScript source types supported), but not for RenderScript. + local includeDirsVariable = iif(androidndk.rsExtensions[sourceExtension] ~= nil, renderScriptIncludeDirsVariable, "C_INCLUDES"); + local includeDirsForExtension = includeDirs[includeDirsVariable]; + if includeDirsForExtension == nil then + includeDirsForExtension = {}; + includeDirs[includeDirsVariable] = includeDirsForExtension; + end + if not configIncludeDirsAdded[includeDirsVariable] then + androidndk.addIncludeDirs(includeDirsForExtension, config); + end + -- Add extension-specific include directories. + -- ndk-build doesn't support per-file include directories, but C/C++/GAS/YASM and RenderScript need to be distinguished from each other. + androidndk.addIncludeDirs(includeDirsForExtension, fileConfig); + + -- Gather compiler flags. + local compilerFlagsVariable = androidndk.compilerFlagsVariables[sourceExtension]; + if compilerFlagsVariable ~= nil then + local compilerFlagsForExtension = compilerFlags[compilerFlagsVariable]; + if compilerFlagsForExtension == nil then + compilerFlagsForExtension = {}; + compilerFlags[compilerFlagsVariable] = compilerFlagsForExtension; + end + -- Add non-extension-specific compiler options from the project configuration if hasn't done already. + -- It's fine not to do filtering if the project, for example, contains only C or C++ files, but no assembly. + if not configCompilerFlagsAdded[compilerFlagsVariable] then + configCompilerFlagsAdded[compilerFlagsVariable] = true; + androidndk.addCompilerFlagsForExtension(compilerFlagsForExtension, sourceExtension, config, temporaryVariables); + end + -- Add extension-specific compiler options. + -- ndk-build doesn't support per-file flags, but C, C++, GAS and YASM need to be distinguished from each other. + -- Doing this after the project-level flags so per-extension flags can override them (provide a -fno- for an -f or the opposite). + androidndk.addCompilerFlagsForExtension(compilerFlagsForExtension, sourceExtension, fileConfig, temporaryVariables); + end + end + end + end + end + end + end + end + end + end + end + }); + + -- Get the extension, or nil if not available, for the special case of precreated project files. + -- These can be external Android.mk files and prebuilt libraries. + -- To use one, it must be the only source file in the project. + local precreatedExtension = nil; + if #sourcePrecreatedFiles == 1 and not (#sourceFiles > 0 or #sourceFilesYasmConditional > 0) then + precreatedExtension = path.getextension(sourcePrecreatedFiles[1]); + end + + if precreatedExtension ~= nil then + -- Check the special case of an external Android.mk file. + -- Using Android.mk files not generated by Premake is allowed as long as: + -- * Only one project is specified in it. + -- * The project name, after all escaping and reference expansion, is the same as LOCAL_MODULE in it. + -- * The kind matches the one used in it. + if precreatedExtension == ".mk" then + p.w("include %s", androidndk.preventWhitespaceTrimming(sourcePrecreatedFiles[1])); + return; + end + + -- Check the special case of a prebuilt library. + local prebuiltKind = androidndk.prebuiltKinds[config.kind]; + if prebuiltKind ~= nil and precreatedExtension == prebuiltKind.extension then + -- Backslash escaping is not supported for prebuilt library paths on Windows. + androidndk.assignToVariablePostEsc("LOCAL_SRC_FILES", sourcePrecreatedFiles[1], false); + p.w("include $(%s)", prebuiltKind.script); + return; + end + end + + -- Warn if there are any external Android.mk files or prebuilt libraries in the projects, but they aren't used for some reason. + -- It may be a mistake, the user might have wanted to use one, but has possibly configured the filters so that other files are still included. + for i, file in ipairs(sourcePrecreatedFiles) do + p.warn( + "Workspace '%s' project '%s' configuration '%s' contains an external Android.mk or a prebuilt library '%s' among its source files, " .. + "but it's not the only source file in the project, or it doesn't match the kind of the project", + config.workspace.name, config.project.name, config.name, file); + end + + -- Some variables may have values that are relevant only to a subset of the ABIs. + -- Examples are LOCAL_ARM_MODE, LOCAL_ARM_NEON, .arm/.neon/.arm.neon and .asm in LOCAL_SRC_FILES. + -- The general rule here is that most of the details of handling those are left to ndk-build itself. + -- This is done to avoid introducing additional interference and constraints, as well as to simplify the code. + -- ABI conditionals are added only when not having them would cause errors or warnings (like x86-specific CFLAGS on ARM). + -- If the default behavior of ndk-build needs to be overriden, the project should explicitly use the needed filters. + + -- Gather C++ settings if the precompiled header is used, from the project and, if available, the file. + -- The precompiled header is always compiled as C++ by ndk-build. + -- Treat it as potentially encountering a C++ file for the first time, so it's compiled with the needed include directories and flags. + -- Ignoring ExcludeFromBuild as it doesn't have effect on pchheader in other Premake actions. + if pch ~= nil then + if not configIncludeDirsAdded["C_INCLUDES"] then + configIncludeDirsAdded["C_INCLUDES"] = true; + local cIncludes = includeDirs["C_INCLUDES"]; + if cIncludes == nil then + cIncludes = {}; + includeDirs["C_INCLUDES"] = cIncludes; + end + androidndk.addIncludeDirs(cIncludes, config); + if pchFileConfig ~= nil then + androidndk.addIncludeDirs(cIncludes, pchFileConfig); + end + end + if not configCompilerFlagsAdded["CPPFLAGS"] then + configCompilerFlagsAdded["CPPFLAGS"] = true; + local cppFlags = compilerFlags["CPPFLAGS"]; + if cppFlags == nil then + cppFlags = {}; + compilerFlags["CPPFLAGS"] = cppFlags; + end + androidndk.addCompilerFlagsForExtension(cppFlags, androidndk.cppExtensions[1], config, temporaryVariables); + if pchFileConfig ~= nil then + androidndk.addCompilerFlagsForExtension(cppFlags, androidndk.cppExtensions[1], pchFileConfig, temporaryVariables); + end + end + end + + -- If the LinkTimeOptimization flag is enabled, apply the LTO type requested by the project explicitly via `buildoptions`, or the default "-flto". + -- Also verify link-time optimization type consistency. + local fltoCOverride = nil; + if compilerFlags["CONLYFLAGS"] ~= nil then + fltoCOverride = compilerFlags["CONLYFLAGS"].flto; + end + local fltoCppOverride = nil; + if compilerFlags["CPPFLAGS"] ~= nil then + fltoCppOverride = compilerFlags["CPPFLAGS"].flto; + end + -- This must not be used by the link options - they should be only verified against it. + -- Static library analysis doesn't scan `buildoptions`, only `linkoptions`. + local fltoBuildOption = fltoCppOverride or fltoCOverride or "-flto"; + if fltoCOverride ~= nil and fltoCOverride ~= fltoBuildOption then + p.warn( + "Workspace '%s' project '%s' configuration '%s' uses LTO type '%s' for C, while it uses '%s' for another language", + config.workspace.name, config.project.name, config.name, fltoCOverride, fltoBuildOption); + end + if fltoCppOverride ~= nil and fltoCppOverride ~= fltoBuildOption then + p.warn( + "Workspace '%s' project '%s' configuration '%s' uses LTO type '%s' for C++, while it uses '%s' for another language", + config.workspace.name, config.project.name, config.name, fltoCppOverride, fltoBuildOption); + end + if config.flags.LinkTimeOptimization then + if fltoCOverride == nil then + if compilerFlags["CONLYFLAGS"] == nil then + compilerFlags["CONLYFLAGS"] = {} + end + if compilerFlags["CONLYFLAGS"].buildoptions == nil then + compilerFlags["CONLYFLAGS"].buildoptions = {} + end + table.insertkeyed(compilerFlags["CONLYFLAGS"].buildoptions, fltoBuildOption); + end + if fltoCppOverride == nil then + if compilerFlags["CPPFLAGS"] == nil then + compilerFlags["CPPFLAGS"] = {} + end + if compilerFlags["CPPFLAGS"].buildoptions == nil then + compilerFlags["CPPFLAGS"].buildoptions = {} + end + table.insertkeyed(compilerFlags["CPPFLAGS"].buildoptions, fltoBuildOption); + end + end + + -- Gather linker options (LDFLAGS and LDLIBS) from the module and its static library dependencies. + -- Importing manually instead of using LOCAL_EXPORT_LDFLAGS/LDLIBS so there's no transitivity across shared libraries. + -- This is consistent with the behavior of Visual Studio - only static libraries export their dependencies. + -- Also it keeps syslibdirs of all static library dependencies last, after all local library directories. + -- ndk-build puts imported LDFLAGS first, but imported LDLIBS last. + -- For -u, which is usually passed via LDFLAGS, the order of local vs. imported options doesn't matter, however. + -- all_depends in ndk-build is generated via a breadth-first walk of the dependency graph. + local isLinked = config.kind == p.CONSOLEAPP or config.kind == p.SHAREDLIB; + local ldFlags = {}; + local ldLibs = {}; + if isLinked then + local ldFlagsUndefined = {}; + local ldFlagsLocal = {}; + local ldLibsDirFlags = {}; + local ldLibsSysDirFlags = {}; + local ldLibsLibFlags = {}; + local ldLinkTimeOptimization = config.flags.LinkTimeOptimization; + local ldFlagsExplicitFlto = nil; + -- Start recursion from the current project config. + -- It will also result in local LDLIBS parts being added before the imports. + local ldDependencies = { config, [config.project.name] = config }; + local ldDependencyIndex = 1; + while ldDependencyIndex <= #ldDependencies do + -- Gather -u LDFLAGS as well as LDLIBS parts for the project currently being processed. + -- -u may be used to keep certain exports from static libraries in shared libraries, in a way more granular than whole static libraries. + -- It is used, for example, to prevent stripping ANativeActivity_onCreate from the Android Native App Glue. + local ldDependency = ldDependencies[ldDependencyIndex]; + local ldDependencyExplicitFlto = + androidndk.addSingleConfigLinkerFlags( + ldDependency, ldFlagsUndefined, nil, ldLibsDirFlags, ldLibsSysDirFlags, ldLibsLibFlags, temporaryVariables); + -- The last -flto has the highest priority. + -- However, -flto for the project itself is actually added after all dependencies here, not alongside them. + if ldDependency ~= config and ldDependencyExplicitFlto ~= nil then + if ldFlagsExplicitFlto ~= nil and ldFlagsExplicitFlto ~= ldDependencyExplicitFlto then + p.warn( + "Workspace '%s' project '%s' configuration '%s' has mismatching -flto link options " .. + "among its static library dependencies ('%s' in project '%s' and '%s' in another project)", + config.workspace.name, config.project.name, config.name, + ldDependencyExplicitFlto, ldDependency.project.name, ldFlagsExplicitFlto); + end + ldFlagsExplicitFlto = ldDependencyExplicitFlto; + end + for i, ldDependencySibling in ipairs(p.config.getlinks(ldDependency, "siblings", "object")) do + -- Only gather -u exports and as LDLIBS from static libraries, as shared libraries have already been linked as a complete object. + -- Also check if not already handled, including to prevent circular dependencies. + if ldDependencySibling.kind == p.STATICLIB and ldDependencies[ldDependencySibling.project.name] == nil then + if androidndk.isProjectSupported(ldDependencySibling.project, false) then + if androidndk.isConfigSupported(ldDependencySibling, false) then + table.insert(ldDependencies, ldDependencySibling); + ldDependencies[ldDependencySibling.project.name] = ldDependencySibling; + if ldDependencySibling.flags.LinkTimeOptimization then + ldLinkTimeOptimization = true; + end + end + end + end + end + ldDependencyIndex = ldDependencyIndex + 1; + end + -- Merge LDLIBS parts. + local ldLibsFlagsTables = { ldLibsDirFlags, ldLibsSysDirFlags, ldLibsLibFlags }; + for i, ldLibsFlags in ipairs(ldLibsFlagsTables) do + for i2, ldLibsFlag in ipairs(ldLibsFlags) do + table.insertkeyed(ldLibs, ldLibsFlag); + end + end + -- Gather local LDFLAGS other than -u after the imports. + -- For LDFLAGS, the order mostly shouldn't matter though. + -- Doing this just in a way consistent with how ndk-build itself gathers exported LDLIBS. + local ldLocalFlagsExplicitFlto = androidndk.addSingleConfigLinkerFlags(config, nil, ldFlagsLocal, nil, nil, nil, temporaryVariables); + if ldLocalFlagsExplicitFlto ~= nil then + -- The last -flto has the highest priority. + if ldFlagsExplicitFlto ~= nil and ldFlagsExplicitFlto ~= ldLocalFlagsExplicitFlto then + p.warn( + "Workspace '%s' project '%s' configuration '%s' has a -flto link option '%s' " .. + "that doesn't match its value used by static library dependencies '%s'", + config.workspace.name, config.project.name, config.name, + ldLocalFlagsExplicitFlto, ldFlagsExplicitFlto); + end + ldFlagsExplicitFlto = ldLocalFlagsExplicitFlto; + end + if ldFlagsExplicitFlto ~= nil then + ldLinkTimeOptimization = true; + end + -- If the project itself, or any of its static libraries, is compiled with LTO, link with LTO. + -- Also, if the project or any of its static libraries has an explicit -flto option (possibly with a non-default type), use it instead. + local ldFlagsFlto = ldFlagsExplicitFlto or "-flto"; + -- Checking if the build -flto is not nil because the project may, for instance, only link against static libraries with LTO. + if fltoBuildOption ~= nil and fltoBuildOption ~= ldFlagsFlto then + if ldFlagsFlto ~= nil then + p.warn( + "Workspace '%s' project '%s' configuration '%s' uses a -flto build option '%s' " .. + "that differs from the value '%s' that will be used by the linker", + config.workspace.name, config.project.name, config.name, fltoBuildOption, ldFlagsFlto); + else + p.warn( + "Workspace '%s' project '%s' configuration '%s' uses a -flto build option '%s', " .. + "but doesn't have the LinkTimeOptimization flag enabled or an -flto in its link options", + config.workspace.name, config.project.name, config.name, fltoBuildOption); + end + end + if ldLinkTimeOptimization then + table.insertkeyed(ldFlags, ldFlagsFlto); + end + -- Merge LDFLAGS parts. + local ldFlagsTables = { ldFlagsUndefined, ldFlagsLocal }; + for i, ldFlagsTable in ipairs(ldFlagsTables) do + for i2, ldFlag in ipairs(ldFlagsTable) do + table.insertkeyed(ldFlags, ldFlag); + end + end + end + + -- Gather module dependencies for the current build configuration and platform. + local sharedLibraries = {}; + local staticLibraries = {}; + local wholeStaticLibraries = {}; + for i, siblingLinkProjectConfig in ipairs(p.config.getlinks(config, "siblings", "object")) do + if androidndk.isProjectSupported(siblingLinkProjectConfig.project, false) then + if androidndk.isConfigSupported(siblingLinkProjectConfig, false) then + local siblingLinksTable = nil; + if siblingLinkProjectConfig.kind == p.SHAREDLIB then + siblingLinksTable = sharedLibraries; + elseif siblingLinkProjectConfig.kind == p.STATICLIB then + if siblingLinkProjectConfig.wholelib == true or config.wholelibs[siblingLinkProjectConfig.project.name] ~= nil then + siblingLinksTable = wholeStaticLibraries; + else + siblingLinksTable = staticLibraries; + end + end + if siblingLinksTable ~= nil then + table.insert(siblingLinksTable, siblingLinkProjectConfig.project.name); + end + end + end + end + + -- Assign the values to the variables. + + -- Write assignments to referenced intermediate variables. + for i, temporaryVariable in ipairs(temporaryVariables) do + androidndk.assignToVariablePostEsc(androidndk.temporaryVariablePrefix .. i, temporaryVariable, false); + end + + -- LOCAL_ALLOW_UNDEFINED_SYMBOLS + if isLinked and config.undefinedsymbols == true then + p.w("LOCAL_ALLOW_UNDEFINED_SYMBOLS := true"); + end + + -- LOCAL_ASFLAGS + androidndk.writeProjectCompilerFlags(compilerFlags, "ASFLAGS", true); + + -- LOCAL_ASMFLAGS + androidndk.writeProjectCompilerFlags(compilerFlags, "ASMFLAGS", true); + + -- LOCAL_ARM_MODE + -- NDK uses T32 by default, and always switches to A32 for debug builds, but it's handled implicitly in it. + if configUsesA32 then + p.w("LOCAL_ARM_MODE := arm"); + end + + -- LOCAL_ARM_NEON + -- On NDK r21, NEON is enabled by default. + -- Since that wasn't the case on older versions, both enabling and disabling it explicitly anyway. + p.w("LOCAL_ARM_NEON := %s", iif(configUsesNeon, "true", "false")); + + -- LOCAL_CONLYFLAGS + -- Potentially will be appending ISA and vector extensions, post-process later. + local cOnlyFlagsNeedPostProcess = androidndk.writeProjectCompilerFlags(compilerFlags, "CONLYFLAGS", false); + + -- LOCAL_CPPFLAGS + -- Potentially will be appending ISA and vector extensions, post-process later. + local cppFlagsNeedPostProcess = androidndk.writeProjectCompilerFlags(compilerFlags, "CPPFLAGS", false); + + -- After writing LOCAL_CONLYFLAGS and LOCAL_CPPFLAGS, add ABI-specific C and C++ flags (not using LOCAL_CFLAGS at all). + local cFlagsAbis; + if configAbi == androidndk.ABI_ALL then + cFlagsAbis = androidndk.knownAbis; + else + cFlagsAbis = { configAbi }; + end + local abiCFlagsConditionalOpen = false; + for i, cFlagsAbi in ipairs(cFlagsAbis) do + local abiCFlags = {}; + -- vectorextensions + if config.vectorextensions ~= nil then + local abiVectorExtensions = androidndk.abiVectorExtensions[cFlagsAbi]; + if abiVectorExtensions ~= nil then + local abiConfigVectorExtensions = abiVectorExtensions[config.vectorextensions]; + if abiConfigVectorExtensions ~= nil then + table.insertkeyed(abiCFlags, p.esc(abiConfigVectorExtensions)); + end + end + end + -- isaextensions + local abiIsaExtensions = androidndk.abiIsaExtensions[cFlagsAbi]; + if abiIsaExtensions ~= nil then + for i2, extension in ipairs(config.isaextensions) do + local abiIsaExtension = abiIsaExtensions[extension]; + if abiIsaExtension ~= nil then + table.insertkeyed(abiCFlags, p.esc(abiIsaExtension)); + end + end + end + -- Write the conditional and the extensions. + if #abiCFlags > 0 then + if configAbi == androidndk.ABI_ALL then + p.push("%sifeq ($(TARGET_ARCH_ABI),%s)", androidndk.getCaseElse(abiCFlagsConditionalOpen), cFlagsAbi); + abiCFlagsConditionalOpen = true; + end + -- Safe to += even if no other CONLYFLAGS and CPPFLAGS were specified, set to an empty value by CLEAR_VARS. + if androidndk.assignToVariablePostEsc("LOCAL_CONLYFLAGS", abiCFlags, true, androidndk.shellEscapePostQuotesChecker, "+=") then + cOnlyFlagsNeedPostProcess = true; + end + if androidndk.assignToVariablePostEsc("LOCAL_CPPFLAGS", abiCFlags, true, androidndk.shellEscapePostQuotesChecker, "+=") then + cppFlagsNeedPostProcess = true; + end + if configAbi == androidndk.ABI_ALL then + p.pop(); + end + end + end + if abiCFlagsConditionalOpen then + assert(configAbi == androidndk.ABI_ALL, "Can have ABI conditionals for ABI-specific C flags only for ABI-agnostic configurations"); + p.w("endif"); + end + + if cOnlyFlagsNeedPostProcess then + androidndk.writePostProcessCall("LOCAL_CONLYFLAGS", androidndk.shellEscapePostQuotesMakeCall); + end + if cppFlagsNeedPostProcess then + androidndk.writePostProcessCall("LOCAL_CPPFLAGS", androidndk.shellEscapePostQuotesMakeCall); + end + + -- LOCAL_CPP_FEATURES + -- For Clang, Premake core modules check if these are not "Off" (rather than if they are "On"). + local cppFeatures = {}; + if config.exceptionhandling ~= p.OFF then + table.insert(cppFeatures, "exceptions"); + end + if config.rtti ~= p.OFF then + table.insert(cppFeatures, "rtti"); + end + if #cppFeatures > 0 then + androidndk.assignToVariablePostEsc("LOCAL_CPP_FEATURES", cppFeatures, false); + end + + -- LOCAL_C_INCLUDES + androidndk.writeProjectIncludeDirs(includeDirs, "C_INCLUDES", true); + + -- LOCAL_DISABLE_FATAL_LINKER_WARNINGS + -- Different than the Android.mk default (fatal by default), but for compatibility with other Premake actions. + if isLinked and not config.flags.FatalLinkWarnings then + p.w("LOCAL_DISABLE_FATAL_LINKER_WARNINGS := true"); + end + + -- LOCAL_DISABLE_FORMAT_STRING_CHECKS + -- Enabling format string checks by default (if nil). + if config.formatstringchecks == false then + p.w("LOCAL_DISABLE_FORMAT_STRING_CHECKS := true"); + end + + -- LOCAL_LDFLAGS + if isLinked then + if androidndk.assignToVariablePostEsc("LOCAL_LDFLAGS", ldFlags, true, androidndk.shellEscapePostQuotesChecker) then + androidndk.writePostProcessCall("LOCAL_LDFLAGS", androidndk.shellEscapePostQuotesMakeCall); + end + end + + -- LOCAL_LDLIBS + if isLinked then + if androidndk.assignToVariablePostEsc("LOCAL_LDLIBS", ldLibs, true, androidndk.shellEscapePostQuotesChecker) then + androidndk.writePostProcessCall("LOCAL_LDLIBS", androidndk.shellEscapePostQuotesMakeCall); + end + end + + -- LOCAL_MODULE_FILENAME + -- Allowed directly on Linux: !+,-.=@[]^_{}~ + -- Allowed if \-escaped on Linux: "\` + -- Allowed if \-escaped on Linux, misleadingly displayed with \ in the terminal: &'()*<>? + -- : is allowed if escaped on Linux (displayed with \), disallowed on Windows (drive letter separator - only the name, not a path, in this variable). + -- Disallowed: whitespaces, #$%/;| + local moduleFileName = p.esc(config.buildtarget.prefix) .. p.esc(config.buildtarget.basename) .. p.esc(config.buildtarget.suffix); + if androidndk.staticallyHasPatternPostEsc(moduleFileName, "[%s#%$%%/;|]") then + -- % needs to be escaped as %% in printf format strings. + p.warn( + "Using the default build target name for workspace '%s' project '%s' configuration '%s' " .. + "instead of '%s' (displayed as escaped) with whitespaces or disallowed characters #$%%/:;|", + config.workspace.name, config.project.name, config.name, moduleFileName); + else + if androidndk.assignToVariablePostEsc("LOCAL_MODULE_FILENAME", moduleFileName, false, androidndk.shellEscapeModuleFileNameChecker) then + androidndk.writePostProcessCall("LOCAL_MODULE_FILENAME", androidndk.shellEscapeModuleFileNameMakeCall); + end + end + + -- LOCAL_PCH + if pch ~= nil then + if androidndk.assignToVariablePostEsc("LOCAL_PCH", pch, false, androidndk.shellEscapeChecker) then + androidndk.writePostProcessCall("LOCAL_PCH", androidndk.shellEscapeMakeCall); + end + end + + -- LOCAL_RENDERSCRIPT_COMPATIBILITY + if config.renderscriptcompatibility == true then + p.w("LOCAL_RENDERSCRIPT_COMPATIBILITY := true"); + end + + -- LOCAL_RENDERSCRIPT_FLAGS + androidndk.writeProjectCompilerFlags(compilerFlags, "RENDERSCRIPT_FLAGS", true); + + -- LOCAL_RENDERSCRIPT_INCLUDES or LOCAL_RENDERSCRIPT_INCLUDES_OVERRIDE + androidndk.writeProjectIncludeDirs(includeDirs, renderScriptIncludeDirsVariable, true); + + -- LOCAL_SHARED_LIBRARIES + -- See LOCAL_MODULE for character rules. + if androidndk.assignToVariablePostEsc("LOCAL_SHARED_LIBRARIES", p.esc(sharedLibraries), true, androidndk.shellEscapeChecker) then + androidndk.writePostProcessCall("LOCAL_SHARED_LIBRARIES", androidndk.shellEscapeMakeCall); + end + + -- LOCAL_SHORT_COMMANDS + if config.shortcommands == true then + p.w("LOCAL_SHORT_COMMANDS := true"); + end + + -- LOCAL_SRC_FILES + -- See the validation of source files for information about disallowed characters. + local sourceFilesNeedPostProcess = false; + if androidndk.assignToVariablePostEsc("LOCAL_SRC_FILES", sourceFiles, true, androidndk.shellEscapeSrcFilesChecker) then + sourceFilesNeedPostProcess = true; + end + -- Only add .asm files for x86 and x86_64 as otherwise the NDK will be throwing warnings. + -- Single-ABI configurations are already handled while gathering the source file nodes. + -- Write the assignment for multi-ABI configurations. + if #sourceFilesYasmConditional > 0 then + p.push("ifneq ($(filter x86 x86_64,$(TARGET_ARCH_ABI)),)"); + if androidndk.assignToVariablePostEsc("LOCAL_SRC_FILES", sourceFilesYasmConditional, true, androidndk.shellEscapeSrcFilesChecker, "+=") then + sourceFilesNeedPostProcess = true; + end + p.pop("endif"); + end + if sourceFilesNeedPostProcess then + androidndk.writePostProcessCall("LOCAL_SRC_FILES", androidndk.shellEscapeSrcFilesMakeCall); + end + + -- LOCAL_STATIC_LIBRARIES + -- See LOCAL_MODULE for character rules. + if androidndk.assignToVariablePostEsc("LOCAL_STATIC_LIBRARIES", p.esc(staticLibraries), true, androidndk.shellEscapeChecker) then + androidndk.writePostProcessCall("LOCAL_STATIC_LIBRARIES", androidndk.shellEscapeMakeCall); + end + + -- LOCAL_THIN_ARCHIVE + if config.kind == p.STATICLIB and config.thinarchive == true then + p.w("LOCAL_THIN_ARCHIVE := true"); + end + + -- LOCAL_WHOLE_STATIC_LIBRARIES + -- See LOCAL_MODULE for character rules. + if androidndk.assignToVariablePostEsc("LOCAL_WHOLE_STATIC_LIBRARIES", p.esc(wholeStaticLibraries), true, androidndk.shellEscapeChecker) then + androidndk.writePostProcessCall("LOCAL_WHOLE_STATIC_LIBRARIES", androidndk.shellEscapeMakeCall); + end + + -- Invoke the build script for the specified kind. + local kindScript = androidndk.kindScripts[config.kind]; + assert(kindScript ~= nil, "Configurations with invalid kinds must be skipped in isConfigSupported"); + p.w("include $(%s)", kindScript); +end + +function androidndk.onProject(project) + if not androidndk.isProjectSupported(project, true) then + return; + end + androidndk.setupGeneration(); + p.generate(project, ".prj.Android.mk", function(project) + -- Must be synchronized with getEscapedProjectRelativePath. + -- Using the Android.mk directory (location), not the base directory, as it's less likely to contain header files. + -- There's undesirable behavior in NDK regarding the order of include directories. + -- LOCAL_PATH is always implicitly an include directory, and the -I for it is passed after the STL include directories. + -- That causes #include_next in C standard library headers to locate app headers with the same in LOCAL_PATH. + -- https://github.com/android/ndk/issues/1582 + p.w("LOCAL_PATH := $(call my-dir)"); + p.w("include $(CLEAR_VARS)"); + -- Workaround for LOCAL_RENDERSCRIPT_COMPATIBILITY not being cleared in NDK r23 as it's not listed in modules-LOCALS. + -- Clearing similar to clear-vars as of NDK r23, by defining as empty, not via `undefine`. + p.w("LOCAL_RENDERSCRIPT_COMPATIBILITY :="); + -- Project name already verified by androidndk.isProjectSupported. + if androidndk.assignToVariablePostEsc("LOCAL_MODULE", p.esc(project.name), false, androidndk.shellEscapeChecker) then + androidndk.writePostProcessCall("LOCAL_MODULE", androidndk.shellEscapeMakeCall); + end + -- Specify all extensions assumed to be C++ and RenderScript by this module. + -- This allows for using extensions different than the default in this module if needed. + -- Additionally, it ensures forward compatibility if the defaults in ndk-build are changed. + androidndk.assignToVariablePostEsc("LOCAL_CPP_EXTENSION", table.concat(androidndk.cppExtensions, " "), false); + androidndk.assignToVariablePostEsc("LOCAL_RS_EXTENSION", table.concat(androidndk.rsExtensions, " "), false); + -- Gather valid configurations for each ABI. + -- ABI-agnostic configurations are checked last. + -- This allows both ABI specializations and ABI-agnostic fallbacks to be specified for building at the same time. + -- Without this, the ABI-agnostic fallback would've been chosen over specializations depending on the order of the platforms table. + local abisConfigs = {}; + for config in p.project.eachconfig(project) do + if androidndk.isConfigSupported(config, true) then + local configAbi = androidndk.getConfigAbi(config); + if abisConfigs[configAbi] == nil then + abisConfigs[configAbi] = { abi = configAbi, configs = {} }; + -- The ABI-agnostic configurations will be used as fallbacks when no ABI specialization is available. + -- So, they need to be generated last. + if configAbi ~= androidndk.ABI_ALL then + table.insert(abisConfigs, abisConfigs[configAbi]); + end + end + table.insert(abisConfigs[configAbi].configs, config); + end + end + if abisConfigs[androidndk.ABI_ALL] ~= nil then + table.insert(abisConfigs, abisConfigs[androidndk.ABI_ALL]); + end + local anyConfigWritten = false; + for i, abiConfigs in ipairs(abisConfigs) do + for i2, abiConfig in ipairs(abiConfigs.configs) do + local configCondition = androidndk.getConfigCondition(abiConfig.buildcfg, abiConfig.platform, abiConfigs.abi); + p.push("%s%s", androidndk.getCaseElse(anyConfigWritten), configCondition); + androidndk.generateProjectConfig(abiConfig); + p.pop(); + anyConfigWritten = true; + end + end + if anyConfigWritten then + p.w("endif"); + end + end); +end diff --git a/src_rebuild/premake_modules/androidndk/androidndk_workspace.lua b/src_rebuild/premake_modules/androidndk/androidndk_workspace.lua new file mode 100644 index 00000000..1f737045 --- /dev/null +++ b/src_rebuild/premake_modules/androidndk/androidndk_workspace.lua @@ -0,0 +1,513 @@ +-- premake-androidndk - a multi-ABI, multi-language ndk-build Android.mk generator for Premake. +-- Originally written by Vitaliy Kuzmin. +-- See README.md for detailed usage and design information. +-- Available under the Unlicense (see UNLICENSE.txt) or the BSD 3-Clause "New" or "Revised" License (see LICENSE.txt). + +local p = premake; +local androidndk = p.modules.androidndk; + +-- Projects can add their own configurations and platforms. +-- So, the use of workspace.configurations, workspace.projects, and their product workspace.configs, should be avoided. +-- Instead, configs should be gathered from all projects. + +-- Writes the setup of the variables used in configuration conditionals. +-- Required in both Application.mk and the workspace Android.mk because with Gradle, the Application.mk is optional. +function androidndk.setupConfigConditionalMakeVariables(usedBuildcfgs, usedPlatforms) + -- Display generated workspace usage information. + -- Using warning/error directly, not the __ndk_* counterparts. + -- __ndk_* functions are internal, and it's more important to show this to the user than to respect NDK_NO_*. + -- $(info) is not displayed in the build output in Android Studio, using $(warning) for everything. + p.push("ifeq ($(filter %s,$(PREMAKE_ANDROIDNDK_CONFIGURATIONS)),)", table.concat(p.esc(usedBuildcfgs), " ")); + p.w("$(warning No configurations to build are specified in PREMAKE_ANDROIDNDK_CONFIGURATIONS.)"); + p.w("$(warning Specify one or multiple \"PREMAKE_ANDROIDNDK_CONFIGURATIONS+=configuration\" in the ndk-build arguments to build those configurations.)"); + p.w("$(warning For workspaces with multiple target platforms, you can also provide the list of the platforms to build via PREMAKE_ANDROIDNDK_PLATFORMS.)"); + p.w("$(warning If PREMAKE_ANDROIDNDK_PLATFORMS is not specified, the projects in this workspace will be built for all platforms they're targeting.)"); + p.w("$(warning Note that configuration and platform names are case-sensitive in this script.)"); + p.w("$(warning )"); + p.w("$(warning It's heavily recommended that only at most one configuration and platform specified corresponds to each targeted ABI.)"); + p.w("$(warning Otherwise, which set of project settings will actually be chosen for building for each ABI will be undefined.)"); + p.w("$(warning )"); + p.w("$(warning The recommended approach is to use configurations for the optimization mode, and, if needed, platforms for ABI filtering.)"); + p.w("$(warning This can be done by specifying different values of the Premake architecture setting for each platform using a platform filter.)"); + p.w("$(warning In this case, each ABI will unambiguously correspond to only one configuration and platform pair.)"); + p.w("$(warning )"); + p.w("$(warning Configurations for this workspace:)"); + for i, buildcfg in ipairs(usedBuildcfgs) do + p.x("$(warning $() %s)", buildcfg); + end + p.w("$(warning )"); + if #usedPlatforms > 0 then + p.w("$(warning Platforms for this workspace:)"); + for i, platform in ipairs(usedPlatforms) do + p.x("$(warning $() %s)", platform); + end + else + p.w("$(warning This workspace is platform-agnostic.)"); + end + p.w("$(error Aborting.)"); + p.pop("endif"); + + -- Generate variables used for configuration selection. + -- As Application.mk variables are preserved in Android.mk, += may result in duplication. + -- Only using := for this reason, and also not modifying the original PREMAKE_ANDROIDNDK_CONFIGURATIONS/PLATFORMS. + p.w("PREMAKE_ANDROIDNDK_CONFIGURATIONS_PREFIXED := $(addprefix CONFIGURATION=,$(PREMAKE_ANDROIDNDK_CONFIGURATIONS))"); + if #usedPlatforms > 0 then + p.push("ifneq ($(PREMAKE_ANDROIDNDK_PLATFORMS),)"); + p.w("PREMAKE_ANDROIDNDK_PLATFORMS_PREFIXED := $(addprefix PLATFORM=,$(PREMAKE_ANDROIDNDK_PLATFORMS))"); + p.pop(); + p.push("else"); + local usedPlatformsPrefixed = {}; + for i, platform in ipairs(usedPlatforms) do + table.insert(usedPlatformsPrefixed, "PLATFORM=" .. p.esc(platform)); + end + p.w("PREMAKE_ANDROIDNDK_PLATFORMS_PREFIXED := %s", table.concat(usedPlatformsPrefixed, " ")); + p.pop("endif"); + end +end + +function androidndk.findConfigForAppSetting(workspace, buildcfg, platform, predicate) + -- In none of these checks should completely unrequested build configurations or platforms pass. + -- This may lead, for instance, to systemversion for a totally different OS to be selected as a fallback. + + -- Considering the workspace (and, if it doesn't provide the needed value, the start project) highest-priority. + -- Even when requesting platform-specific settings, but the start project is platform-agnostic (nil .platform), still prefer the start project. + -- This makes settings more controllable than when some project can override the setting just because it has a platform specialization. + + -- Try to find in the workspace itself. + for config in p.workspace.eachconfig(workspace) do + if androidndk.isConfigSupported(config, false) then + if config.buildcfg == buildcfg and (config.platform == nil or config.platform == platform) and predicate(config) then + return config; + end + end + end + + -- If didn't find in the workspace itself, try the main project in the workspace - the start project. + if workspace.startproject ~= nil then + local startProject = p.workspace.findproject(workspace, workspace.startproject); + if startProject ~= nil and androidndk.isProjectSupported(startProject, false) then + for config in p.project.eachconfig(startProject) do + if androidndk.isConfigSupported(config, false) then + if config.buildcfg == buildcfg and (config.platform == nil or config.platform == platform) and predicate(config) then + return config; + end + end + end + end + end + + -- This configuration may be used by just a subset of the projects. + -- Platform-specific specializations and platform-agnostic fallbacks are obtained via separate findConfigForAppSetting calls in this case. + -- ?= for platform-agnostic variables is done even if platform conditions pass - no need to look for them here for non-nil platforms. + for project in p.workspace.eachproject(workspace) do + if androidndk.isProjectSupported(project, false) then + for config in p.project.eachconfig(project) do + if androidndk.isConfigSupported(config, false) then + if config.buildcfg == buildcfg and config.platform == platform and predicate(config) then + return config; + end + end + end + end + end + + -- Found nothing - don't add the setting. + return nil; +end + +-- Returns a table of { variable = "APP_...", value = ... }, with the variable values escaped. +-- Expecting the outer code to set APP_DEBUG to false if APP_OPTIM is release in the end to match Premake optimize/symbols logic. +function androidndk.gatherEscapedAppVariables(workspace, buildcfg, platform) + -- If the value for a Premake setting is not specified by the projects for this configuration, the default must not be added to the table. + -- This would make it impossible for another configuration, where the setting is explicitly defined, to override the value using ?=. + -- Only returning variables corresponding to settings explicitly defined for this configuration. + + -- ndk-build defaults to non-debug (potentially no symbols) and optimized. + -- Premake doesn't define a default for symbols, but unoptimized by default. + -- Replicating the p.config.isDebugBuild and p.config.isOptimizedBuild logic. + -- An optimized build is not considered a debug one at all, regardless of whether symbols are needed. + local optimizeConfig = androidndk.findConfigForAppSetting(workspace, buildcfg, platform, function(config) + return config.optimize ~= nil; + end); + -- optimizeConfig.optimize ~= nil checked previously. + local isOptimized = optimizeConfig ~= nil and optimizeConfig.optimize ~= p.OFF and optimizeConfig.optimize ~= "Debug"; + local appOptim = nil; + if optimizeConfig ~= nil then + -- The configuration explicitly wants to enable or to disable optimizations. + appOptim = iif(isOptimized, "release", "debug"); + end + -- Expecting the outer code to set APP_DEBUG to false if APP_OPTIM is release. + -- Thus, not explicitly returning APP_DEBUG ?= false for release APP_OPTIM. + local appDebug = nil; + if not isOptimized then + local symbolsConfig = androidndk.findConfigForAppSetting(workspace, buildcfg, platform, function(config) + return config.symbols ~= nil; + end); + if symbolsConfig ~= nil then + -- p.config.isOptimizedBuild checked previously. + appDebug = iif(symbolsConfig.symbols ~= p.OFF and symbolsConfig.symbols ~= p.DEFAULT, "true", "false"); + end + end + + local appVariables = {}; + + -- APP_DEBUG + if appDebug ~= nil then + table.insert(appVariables, { variable = "APP_DEBUG", value = appDebug }); + end + + -- APP_OPTIM + if appOptim ~= nil then + table.insert(appVariables, { variable = "APP_OPTIM", value = appOptim }); + end + + -- APP_PLATFORM + local systemVersionConfig = androidndk.findConfigForAppSetting(workspace, buildcfg, platform, function(config) + return p.project.systemversion(config) ~= nil; + end); + if systemVersionConfig ~= nil then + table.insert(appVariables, { variable = "APP_PLATFORM", value = "android-" .. p.esc(p.project.systemversion(systemVersionConfig)) }); + end + + -- PREMAKE_ANDROIDNDK_APP_STL_RUNTIME (part of APP_STL) + local stlConfig = androidndk.findConfigForAppSetting(workspace, buildcfg, platform, function(config) + return config.cppstl ~= nil; + end); + if stlConfig ~= nil then + -- The default, which in ndk-build is "none", is explicitly requested for this configuration. + local stl = iif(stlConfig.cppstl == p.DEFAULT, "none", stlConfig.cppstl); + table.insert(appVariables, { variable = "PREMAKE_ANDROIDNDK_APP_STL_RUNTIME", value = p.esc(stl) }); + end + + -- PREMAKE_ANDROIDNDK_APP_STL_LINKAGE (part of APP_STL) + -- While for ndk-build, the default STL is "none", which doesn't have a linkage suffix, for CMake it's "c++_static". + -- Therefore, considering static the default (treating explicitly specified "Default" as "On"). + local staticRuntimeConfig = androidndk.findConfigForAppSetting(workspace, buildcfg, platform, function(config) + return config.staticruntime ~= nil; + end); + if staticRuntimeConfig ~= nil then + local stlLinkage = iif(staticRuntimeConfig.staticruntime ~= p.OFF, "_static", "_shared"); + table.insert(appVariables, { variable = "PREMAKE_ANDROIDNDK_APP_STL_LINKAGE", value = stlLinkage }); + end + + return appVariables; +end + +function androidndk.onWorkspace(workspace) + -- Not allowing references or escaped $ in workspace names as they complicate path building as well as specifying APP_BUILD_SCRIPT. + -- Premake treats any path beginning with $ as absolute. + -- APP_BUILD_SCRIPT also doesn't allow #$ and whitespaces. + if string.find(workspace.name, "%$") ~= nil or androidndk.staticallyHasPatternPostEsc(p.esc(workspace.name), "[%s#%$]") then + p.warn("Skipping workspace '%s' with name containing GNU make references, whitespaces or disallowed characters #$", workspace.name); + return; + end + + androidndk.setupGeneration(); + + -- Gather build configurations and platforms used by all projects for generating conditionals for application settings. + -- Projects may add their configurations not present in the workspace itself, and they won't appear in workspace.configs. + -- Some projects may have no platforms specified. + -- In this case, they're built regardless of the platform, and also if some completely different platform is specified. + -- At least one build configuration is required in a project, however. + local usedBuildcfgs = {}; + local usedPlatforms = {}; + for project in p.workspace.eachproject(workspace) do + if androidndk.isProjectSupported(project, false) then + for config in p.project.eachconfig(project) do + if androidndk.isConfigSupported(config, false) then + table.insertkeyed(usedBuildcfgs, config.buildcfg); + if config.platform ~= nil then + table.insertkeyed(usedPlatforms, config.platform); + end + end + end + end + end + + -- Application.mk. + p.generate(workspace, ".Application.mk", function(workspace) + -- Verify the correctness of the arguments, and set up the variables used for filtering in Application.mk. + androidndk.setupConfigConditionalMakeVariables(usedBuildcfgs, usedPlatforms); + + -- Gather Application.mk variable values for selected configurations and platforms. + -- As this is Application.mk, ABI filtering is not possible. + -- Therefore, selection of the required build configurations and platforms will work differently than in projects. + -- All selected build configurations and platforms must have the same values of settings written here. + -- For example, APP_OPTIM may be wrong with `PREMAKE_ANDROIDNDK_CONFIGURATIONS := Debug Release` if they have different `optimize`. + -- If one selected configuration-platform defines a value, while another doesn't care, pick from the one where it's explicitly set. + -- So, using if/if and ?= instead of if/elseif and :=, unlike in projects (where only configuration-platform pair is supposed to be chosen). + -- Most APP variables accept only one value - using ?= for them. + -- APP_ABI, however, accumulates the needed ABIs (in this case, for selected configurations and platforms), so using += for it. + + -- First, clear values that will be set - they might have been set externally while invoking ndk-build, override them. + -- Setting them to an empty value is not sufficient - `undefine` is required for ?= to work. + -- clear-vars is called for known APP variables before including Application.mk, which, as of NDK r23, defines the values as empty, however. + -- For this reason, if no value is provided, defining each of these variables as something (at least as empty). + p.w("undefine APP_ABI"); + p.w("undefine APP_DEBUG"); + p.w("undefine APP_OPTIM"); + p.w("undefine APP_PLATFORM"); + p.w("undefine PREMAKE_ANDROIDNDK_APP_STL_RUNTIME"); + p.w("undefine PREMAKE_ANDROIDNDK_APP_STL_LINKAGE"); + + -- Gather ABIs the projects are built for, for each configuration and platform for it. + -- Can't just collect all ABIs used by all platforms into a single APP_ABI assignment. + -- The reason is that some configurations may not even be targeting Android. + -- For instance, may only want ARM builds for Android, but x86 builds only for Windows. + -- If "all" is present in any platform-specific or platform-agnostic table, the whole platform must be treated as using "all". + local buildcfgsAbis = { + -- [1...] = [buildcfg] = { + -- platformSpecific = { + -- [1...] = [platform] = { + -- [1...] = [abi] = abi, + -- } + -- }, + -- platformAgnostic = { + -- [1...] = [abi] = abi, + -- }, + -- } + }; + local abiAgnosticConfigsUsed = false; + for project in p.workspace.eachproject(workspace) do + if androidndk.isProjectSupported(project, false) then + for config in p.project.eachconfig(project) do + if androidndk.isConfigSupported(config, false) then + local buildcfgAbis = buildcfgsAbis[config.buildcfg]; + if buildcfgAbis == nil then + buildcfgAbis = { platformSpecific = {}, platformAgnostic = {} }; + buildcfgsAbis[config.buildcfg] = buildcfgAbis; + end + local platformAbis; + if config.platform ~= nil then + platformAbis = buildcfgAbis.platformSpecific[config.platform]; + if platformAbis == nil then + platformAbis = {}; + buildcfgAbis.platformSpecific[config.platform] = platformAbis; + end + else + platformAbis = buildcfgAbis.platformAgnostic; + end + local abi = androidndk.getConfigAbi(config); + table.insertkeyed(platformAbis, abi); + if abi == androidndk.ABI_ALL then + abiAgnosticConfigsUsed = true; + end + end + end + end + end + + -- Gather the variables, and write the ABIs and variables. + for i, buildcfg in ipairs(usedBuildcfgs) do + local buildcfgConditionalOpen = false; + + local buildcfgAbis = buildcfgsAbis[buildcfg]; + -- Skip ABIs needed by platform-agnostic projects with this configuration from platform specializations. + -- ABIs needed by platform-agnostic projects will be added regardless of the platform. + local platformAgnosticAbis = nil; + local platformAgnosticAbisAll = false; + if buildcfgAbis ~= nil then + platformAgnosticAbis = buildcfgAbis.platformAgnostic; + platformAgnosticAbisAll = platformAgnosticAbis[androidndk.ABI_ALL] ~= nil; + end + + -- Gather and write platform-specific ABIs and platform specializations of APP variables. + for i2, platform in ipairs(usedPlatforms) do + -- Gather ABIs that any projects, for this buildcfg-platform pair, need to be built for. + -- Skip ABIs needed by platform-agnostic projects with this configuration from platform specializations. + -- ABIs needed by platform-agnostic projects will be added regardless of the platform. + local platformNewAbis = {}; + if buildcfgAbis ~= nil and not platformAgnosticAbisAll then + if buildcfgAbis ~= nil then + local platformAbisUnfiltered = buildcfgAbis.platformSpecific[platform]; + if platformAbisUnfiltered ~= nil then + for i3, abi in ipairs(platformAbisUnfiltered) do + if abi == androidndk.ABI_ALL then + platformNewAbis = { androidndk.ABI_ALL }; + break; + end + if platformAgnosticAbis == nil or platformAgnosticAbis[abi] == nil then + table.insert(platformNewAbis, abi); + end + end + -- Sort alphabetically for stable output. + table.sort(platformNewAbis); + end + end + end + -- Gather specializations of the APP variables for this platform. + local platformAppVariables = androidndk.gatherEscapedAppVariables(workspace, buildcfg, platform); + -- Write ABI additions and variable specializations for this platform. + if #platformNewAbis > 0 or #platformAppVariables > 0 then + if not buildcfgConditionalOpen then + buildcfgConditionalOpen = true; + p.push("ifneq ($(filter CONFIGURATION=%s,$(PREMAKE_ANDROIDNDK_CONFIGURATIONS_PREFIXED)),)", p.esc(buildcfg)); + end + p.push("ifneq ($(filter PLATFORM=%s,$(PREMAKE_ANDROIDNDK_PLATFORMS_PREFIXED)),)", p.esc(platform)); + androidndk.assignToVariablePostEsc("APP_ABI", platformNewAbis, false, nil, "+="); + for i3, variable in ipairs(platformAppVariables) do + androidndk.assignToVariablePostEsc(variable.variable, variable.value, false, nil, "?="); + end + -- Close the platform conditional. + p.pop("endif"); + end + end + + -- Write ABIs for platform-agnostic projects and APP variable values used when no platform specialization has been chosen. + local platformAgnosticAbisSorted = nil; + if platformAgnosticAbis ~= nil then + if platformAgnosticAbisAll then + platformAgnosticAbisSorted = { androidndk.ABI_ALL }; + else + platformAgnosticAbisSorted = table.arraycopy(platformAgnosticAbis); + -- Sort alphabetically for stable output. + table.sort(platformAgnosticAbisSorted); + end + end + local platformAgnosticAppVariables = androidndk.gatherEscapedAppVariables(workspace, buildcfg, nil); + if (platformAgnosticAbisSorted ~= nil and #platformAgnosticAbisSorted > 0) or #platformAgnosticAppVariables > 0 then + if not buildcfgConditionalOpen then + buildcfgConditionalOpen = true; + p.push("ifneq ($(filter CONFIGURATION=%s,$(PREMAKE_ANDROIDNDK_CONFIGURATIONS_PREFIXED)),)", p.esc(buildcfg)); + end + if platformAgnosticAbisSorted ~= nil then + androidndk.assignToVariablePostEsc("APP_ABI", platformAgnosticAbisSorted, false, nil, "+="); + end + for i2, variable in ipairs(platformAgnosticAppVariables) do + androidndk.assignToVariablePostEsc(variable.variable, variable.value, false, nil, "?="); + end + end + + if buildcfgConditionalOpen then + p.pop("endif"); + end + end + + -- Apply defaults if no configuration-specific overrides have been chosen, and normalize variables. + -- Also set variables that don't depend on the configuration. + + -- APP_ABI + -- Setting to "all" by default is not needed - empty already means `all`. + -- Also, it can happen only when no configuration with projects to build is selected. + -- Remove duplicates (sorting does that implicitly). + p.w("APP_ABI := $(sort $(APP_ABI))"); + -- If "all" was set for any configuration, and += of any other ABIs happened, make APP_ABI just "all". + if abiAgnosticConfigsUsed then + p.push("ifneq ($(filter " .. androidndk.ABI_ALL .. ",$(APP_ABI)),)"); + p.w("APP_ABI := " .. androidndk.ABI_ALL); + p.pop("endif"); + end + + -- APP_BUILD_SCRIPT + -- In the same directory, no need for p.filename followed by making it relative. + -- Also for this reason, no need for path.join, which may treat the name as an absolute path (for instance, if it begins with a $()\#-escaped #). + p.w("APP_BUILD_SCRIPT := %s", "$(call my-dir)/" .. p.esc(workspace.name .. ".wks.Android.mk")); + + -- APP_DEBUG and APP_OPTIM + -- Handling according to p.config.isDebugBuild and p.config.isOptimizedBuild logic (unoptimized by default, no symbols by default). + -- p.config.isDebugBuild always returns false (no symbols) for optimized builds. + -- For more information, see APP_DEBUG and APP_OPTIM gathering. + p.w("APP_OPTIM ?= debug"); + p.push("ifeq ($(APP_OPTIM),release)"); + p.w("APP_DEBUG := false"); + p.pop(); + p.push("else"); + p.w("APP_DEBUG ?= false"); + p.pop("endif"); + + -- APP_PLATFORM + -- Reverting the `undefine` because as of NDK r23, ndk-build sets all APP variables to empty values. + p.w("APP_PLATFORM ?="); + + -- APP_STL + -- The default for ndk-build is "none". Also, since the default for CMake is "c++_static", assuming static linkage by default. + p.w("PREMAKE_ANDROIDNDK_APP_STL_RUNTIME ?= none"); + p.w("PREMAKE_ANDROIDNDK_APP_STL_LINKAGE ?= _static"); + -- "none" and "system" don't have linkage suffixes. + p.push("ifneq ($(filter none system,$(PREMAKE_ANDROIDNDK_APP_STL_RUNTIME)),)"); + p.w("PREMAKE_ANDROIDNDK_APP_STL_LINKAGE :="); + p.pop("endif"); + p.w("APP_STL := $(PREMAKE_ANDROIDNDK_APP_STL_RUNTIME)$(PREMAKE_ANDROIDNDK_APP_STL_LINKAGE)"); + end); + + -- Android.mk. + p.generate(workspace, ".wks.Android.mk", function(workspace) + -- my-dir returns the directory containing the latest included file, not the directory with the current file. + -- Therefore, if project makefiles are written to other directories, calling it every time will result in incorrect paths. + p.w("PREMAKE_ANDROIDNDK_WORKSPACE_DIR := $(call my-dir)"); + + -- Verify the correctness of the arguments, and set up the variables used for filtering in Android.mk. + -- This needs to be in Android.mk even though it inherits Application.mk variables because with Gradle, Application.mk is optional. + androidndk.setupConfigConditionalMakeVariables(usedBuildcfgs, usedPlatforms); + + -- Setup post-expansion escaping in text passed to command execution via the shell. + -- In some variables - LOCAL_CFLAGS/LOCAL_LDFLAGS, LOCAL_C_INCLUDES, LOCAL_MODULE_FILENAME - path requirements are pretty relaxed. + -- On Linux, file names may contain " or \, but they need to be escaped with \ prefix as otherwise they're interpreted by the shell. + -- On Windows, " is not allowed in file names, but a single \ is treated as a path separator - no escaping required. + -- Function for calling inside quoted arguments (to be followed by the function for a list of arguments). + p.w("%s = $(subst \",\\\",$(subst \\,\\\\,$(1)))", androidndk.shellEscapePreQuotesMakeCall); + -- Function for calling for lists of quoted arguments. + local escapeFunction = { androidndk.shellEscapePostQuotesMakeCall, "_NO_BRACKETS = " }; + local bracketsEncountered = 0; + for i = #androidndk.shellEscapedCharactersPostQuotes, 1, -1 do + local character = androidndk.shellEscapedCharactersPostQuotes[i]; + if character == "(" or character == ")" then + -- Brackets must be used in a ${} call, not $(). + bracketsEncountered = bracketsEncountered + 1; + else + if character == "#" then + -- Escape the comment character similar to the way androidndk.esc does that, breaking the dependency on the number of backslashes. + character = androidndk.commentEscapeString; + elseif character == "$" then + character = "$$"; + end + table.insert(escapeFunction, "$(subst "); + table.insert(escapeFunction, character); + table.insert(escapeFunction, ",\\"); + table.insert(escapeFunction, character); + table.insert(escapeFunction, ","); + end + end + table.insert(escapeFunction, "$(1)"); + table.insert(escapeFunction, string.rep(")", #androidndk.shellEscapedCharactersPostQuotes - bracketsEncountered)); + p.w(table.concat(escapeFunction)); + -- Escape the brackets as well. + p.w( + "%s = ${subst ),\\),${subst (,\\(,${call %s_NO_BRACKETS,${1}}}}", + androidndk.shellEscapePostQuotesMakeCall, + androidndk.shellEscapePostQuotesMakeCall); + -- Function for raw text without arguments containing whitespaces that need to be wrapped in true, unescaped quotes. + p.w( + "%s = $(call %s,$(call %s,$(1)))", + androidndk.shellEscapeMakeCall, + androidndk.shellEscapePostQuotesMakeCall, + androidndk.shellEscapePreQuotesMakeCall); + -- Function for LOCAL_MODULE_FILENAME. + -- : must be \-escaped on Linux. + -- It's a drive letter separator on Windows, however, so it's disallowed in LOCAL_MODULE_FILENAME there (it's a name, not a path). + -- Therefore, there's no need to handle it separately on Windows and Linux - just \-escape : unconditionally. + p.w("%s = $(subst :,\\:,$(call %s,$(1)))", androidndk.shellEscapeModuleFileNameMakeCall, androidndk.shellEscapeMakeCall); + -- Function for LOCAL_SRC_FILES and LOCAL_PCH. + -- : must be \-escaped on Linux, but cannot be escaped on non-Cygwin Windows, and is a drive letter separator there supported directly. + p.push("ifeq ($(HOST_OS),windows)"); + p.w("%s = $(call %s,$(1))", androidndk.shellEscapeSrcFilesMakeCall, androidndk.shellEscapeMakeCall); + p.pop(); + p.push("else"); + p.w("%s = $(subst :,\\:,$(call %s,$(1)))", androidndk.shellEscapeSrcFilesMakeCall, androidndk.shellEscapeMakeCall); + p.pop("endif"); + + -- Include makefiles of all projects. + -- Same path logic as in p.generate. + local workspaceDirectory = path.getdirectory(p.filename(workspace, ".wks.Android.mk")); + for project in p.workspace.eachproject(workspace) do + if androidndk.isProjectSupported(project, false) then + p.w( + "include %s", + androidndk.preventWhitespaceTrimming( + path.join( + "$(PREMAKE_ANDROIDNDK_WORKSPACE_DIR)", + p.esc(path.getrelative(workspaceDirectory, p.filename(project, ".prj.Android.mk")))))); + end + end + end); +end From 6b6ab5806b1d246170737bbe1bdee3ee6a52a20a Mon Sep 17 00:00:00 2001 From: Ilya Shurumov Date: Sun, 18 Dec 2022 23:35:31 +0600 Subject: [PATCH 02/20] - change use of define USE_PGXP --- src_rebuild/Game/C/motion_c.c | 4 ++-- src_rebuild/Game/C/sky.c | 22 +++++++++---------- src_rebuild/Game/C/system.c | 2 +- src_rebuild/Game/C/system.h | 2 +- src_rebuild/Game/C/tile.c | 12 +++++----- src_rebuild/PsyCross | 2 +- .../utils/video_source/VideoPlayer.cpp | 2 +- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src_rebuild/Game/C/motion_c.c b/src_rebuild/Game/C/motion_c.c index 7f7da3cc..c94bec7c 100644 --- a/src_rebuild/Game/C/motion_c.c +++ b/src_rebuild/Game/C/motion_c.c @@ -16,7 +16,7 @@ #include "cars.h" #include "convert.h" -#ifdef USE_PGXP +#if USE_PGXP #include #endif @@ -607,7 +607,7 @@ void DrawBodySprite(LPPEDESTRIAN pDrawingPed, int boneId, VERTTYPE v1[2], VERTTY prims->x3 = v2[0] - FIXEDH(cs) - dx1; prims->y3 = v2[1] - FIXEDH(sn) - dy1; -#ifdef USE_PGXP +#if USE_PGXP if (!bDoingShadow) // [A] Psy-X is currently incorrectly offsets the offscreen PGXP geometry. We don't need it anyway. { ushort pgxpIdx = PGXP_GetIndex(0) - 64; diff --git a/src_rebuild/Game/C/sky.c b/src_rebuild/Game/C/sky.c index e6e1be22..65cf854e 100644 --- a/src_rebuild/Game/C/sky.c +++ b/src_rebuild/Game/C/sky.c @@ -285,7 +285,7 @@ void LoadSky(void) } // [D] [T] -#ifdef USE_PGXP +#if USE_PGXP void DisplaySun(DVECTORF* pos, CVECTOR* col, int flare_col) #else void DisplaySun(DVECTOR* pos, CVECTOR* col, int flare_col) @@ -393,7 +393,7 @@ void DisplaySun(DVECTOR* pos, CVECTOR* col, int flare_col) } // [D] [T] -#ifdef USE_PGXP +#if USE_PGXP void DisplayMoon(DVECTORF* pos, CVECTOR* col, int flip) #else void DisplayMoon(DVECTOR* pos, CVECTOR* col, int flip) @@ -492,7 +492,7 @@ void DrawLensFlare(void) int haze_col; -#ifdef USE_PGXP +#if USE_PGXP DVECTORF sun_pers_conv_position; #else DVECTOR sun_pers_conv_position; @@ -644,7 +644,7 @@ void DrawLensFlare(void) } } -#ifdef USE_PGXP +#if USE_PGXP // remap PsyX_GetPSXWidescreenMappedViewport(&viewp); sun_pers_conv_position.vx = RemapVal(sun_pers_conv_position.vx, float(viewp.x), float(viewp.w), 0.0f, 320.0f); @@ -815,7 +815,7 @@ void calc_sky_brightness(RGB16* skycolor) skycolor->b = skyFade; } -#ifdef USE_PGXP +#if USE_PGXP DVECTORF scratchPad_skyVertices[35]; // 1f800044 #else #define scratchPad_skyVertices ((DVECTOR*)getScratchAddr(0x11)) // 1f800044 @@ -831,7 +831,7 @@ void PlotSkyPoly(POLYFT4* polys, int skytexnum, unsigned char r, unsigned char g src = polys; poly = (POLY_FT4*)current->primptr; -#ifdef USE_PGXP +#if USE_PGXP DVECTORF* outpoints = scratchPad_skyVertices; #else DVECTOR* outpoints = scratchPad_skyVertices; @@ -864,7 +864,7 @@ void PlotSkyPoly(POLYFT4* polys, int skytexnum, unsigned char r, unsigned char g addPrim(current->ot + OTSIZE - 1, poly); -#if defined(USE_PGXP) && defined(USE_EXTENDED_PRIM_POINTERS) +#if USE_PGXP && USE_EXTENDED_PRIM_POINTERS poly->pgxp_index = outpoints[src->v0].pgxp_index; #endif @@ -877,7 +877,7 @@ void PlotHorizonMDL(MODEL* model, int horizontaboffset, RGB16* skycolor) { SVECTOR* verts; -#ifdef USE_PGXP +#if USE_PGXP DVECTORF* dv; #else DVECTOR* dv; @@ -893,7 +893,7 @@ void PlotHorizonMDL(MODEL* model, int horizontaboffset, RGB16* skycolor) dv = scratchPad_skyVertices; count = model->num_vertices; -#ifdef USE_PGXP +#if USE_PGXP PGXP_SetZOffsetScale(0.0f, 256.0f); #endif @@ -906,7 +906,7 @@ void PlotHorizonMDL(MODEL* model, int horizontaboffset, RGB16* skycolor) if(count == 15) gte_stszotz(&z); -#ifdef USE_PGXP +#if USE_PGXP // store PGXP index // HACK: -1 is needed here for some reason dv[0].pgxp_index = dv[1].pgxp_index = dv[2].pgxp_index = PGXP_GetIndex(0) - 1; @@ -916,7 +916,7 @@ void PlotHorizonMDL(MODEL* model, int horizontaboffset, RGB16* skycolor) count -= 3; } while (count); -#ifdef USE_PGXP +#if USE_PGXP PGXP_SetZOffsetScale(0.0f, 1.0f); #endif diff --git a/src_rebuild/Game/C/system.c b/src_rebuild/Game/C/system.c index ac185f3d..614a68b8 100644 --- a/src_rebuild/Game/C/system.c +++ b/src_rebuild/Game/C/system.c @@ -848,7 +848,7 @@ void InitaliseDrawEnv(DB* pBuff, int x, int y, int w, int h) pBuff[1].id = 1; pBuff[1].draw.dfe = 1; -#ifdef USE_PGXP +#if USE_PGXP if(NumPlayers == 2) { pBuff[0].draw.clip.x -= 256; diff --git a/src_rebuild/Game/C/system.h b/src_rebuild/Game/C/system.h index 5ab055e3..029d27c9 100644 --- a/src_rebuild/Game/C/system.h +++ b/src_rebuild/Game/C/system.h @@ -139,7 +139,7 @@ extern DRAW_MODE draw_mode_ntsc; #define OTSIZE 0x2000 #endif -#ifdef USE_EXTENDED_PRIM_POINTERS +#if USE_EXTENDED_PRIM_POINTERS # define PRIMTAB_SIZE 0x50000 #else # define PRIMTAB_SIZE 0x1e000 diff --git a/src_rebuild/Game/C/tile.c b/src_rebuild/Game/C/tile.c index 45551b81..093ba648 100644 --- a/src_rebuild/Game/C/tile.c +++ b/src_rebuild/Game/C/tile.c @@ -32,7 +32,7 @@ void Tile1x1Lit(MODEL* model) else ofse = 133; -#ifdef USE_PGXP +#if USE_PGXP PGXP_SetZOffsetScale(0.0f, ofse > 200 ? 1.005f : 0.995f); #endif @@ -110,7 +110,7 @@ void Tile1x1Lit(MODEL* model) polys = (PL_POLYFT4*)((char*)polys + plotContext.polySizes[ptype]); } -#ifdef USE_PGXP +#if USE_PGXP PGXP_SetZOffsetScale(0.0f, 1.0f); #endif @@ -139,7 +139,7 @@ void Tile1x1(MODEL *model) else ofse = 133; -#ifdef USE_PGXP +#if USE_PGXP PGXP_SetZOffsetScale(0.0f, ofse > 200 ? 1.005f : 0.995f); #endif @@ -193,7 +193,7 @@ void Tile1x1(MODEL *model) polys = (PL_POLYFT4*)((char*)polys + plotContext.polySizes[ptype]); } -#ifdef USE_PGXP +#if USE_PGXP PGXP_SetZOffsetScale(0.0f, 1.0f); #endif @@ -652,7 +652,7 @@ void TileNxN(MODEL *model, int levels, int Dofse) ttype = 0; while (i--) { -#ifdef USE_PGXP +#if USE_PGXP switch (ttype) { case 0: @@ -676,7 +676,7 @@ void TileNxN(MODEL *model, int levels, int Dofse) polys += plotContext.polySizes[*polys]; } -#ifdef USE_PGXP +#if USE_PGXP PGXP_SetZOffsetScale(0.0f, 1.0f); #endif } diff --git a/src_rebuild/PsyCross b/src_rebuild/PsyCross index 8fa92c7f..a04825ea 160000 --- a/src_rebuild/PsyCross +++ b/src_rebuild/PsyCross @@ -1 +1 @@ -Subproject commit 8fa92c7fba6685c0e9f41804c2f5b68dee4b87e7 +Subproject commit a04825ea2c1c5c5eecac83ed97cb637d3cab8928 diff --git a/src_rebuild/utils/video_source/VideoPlayer.cpp b/src_rebuild/utils/video_source/VideoPlayer.cpp index 4f0b2b0d..e4210558 100644 --- a/src_rebuild/utils/video_source/VideoPlayer.cpp +++ b/src_rebuild/utils/video_source/VideoPlayer.cpp @@ -180,7 +180,7 @@ void SetupMovieRectangle(int image_w, int image_h) u_char r = 1; u_char b = 1; -#ifdef USE_PGXP +#if USE_PGXP GR_SetViewPort(0, 0, windowWidth, windowHeight); GrVertex blit_vertices[] = From 8553bdbeff191fcb590c973f6e5a33a49ce49e04 Mon Sep 17 00:00:00 2001 From: Ilya Shurumov Date: Sun, 18 Dec 2022 23:37:16 +0600 Subject: [PATCH 03/20] - HQ font loading redone for further FE font support - added font generator tool - moved DebugOverlay.cpp into utils --- src_rebuild/Game/C/pres.c | 84 +++++----- src_rebuild/Game/C/pres.h | 9 +- src_rebuild/premake5.lua | 52 +++++- src_rebuild/premake5_font_tool.lua | 33 ++++ .../tools/font_tool/font_tool_main.cpp | 156 ++++++++++++++++++ src_rebuild/{ => utils}/DebugOverlay.cpp | 30 ++-- src_rebuild/utils/hqfont.h | 27 +++ src_rebuild/utils/targa.cpp | 56 +++++++ src_rebuild/utils/targa.h | 1 + 9 files changed, 385 insertions(+), 63 deletions(-) create mode 100644 src_rebuild/premake5_font_tool.lua create mode 100644 src_rebuild/tools/font_tool/font_tool_main.cpp rename src_rebuild/{ => utils}/DebugOverlay.cpp (95%) create mode 100644 src_rebuild/utils/hqfont.h diff --git a/src_rebuild/Game/C/pres.c b/src_rebuild/Game/C/pres.c index d6ce8665..0d42e2d3 100644 --- a/src_rebuild/Game/C/pres.c +++ b/src_rebuild/Game/C/pres.c @@ -7,19 +7,24 @@ extern int gShowMap; #ifndef PSX -#define STB_TRUETYPE_IMPLEMENTATION -#include "../utils/stb_truetype.h" -#include "../utils/targa.h" - #include "PsyX/PsyX_render.h" +#include "../utils/targa.h" +#include "../utils/hqfont.h" + #define HIRES_FONTS -#define HIRES_FONT_SIZE_W 768 -#define HIRES_FONT_SIZE_H 512 + +struct FONT_QUAD +{ + float x0, y0, s0, t0; // top-left + float x1, y1, s1, t1; // bottom-right +}; TextureID gHiresFontTexture = 0; TextureID gHiresDigitsTexture = 0; -stbtt_packedchar gSTBCharData[224]; // ASCII 32..126 is 95 glyphs +OUT_FN2RANGE gHiresFontRanges[4]; +OUT_FN2INFO gHiresFontCharData[4][224]; +int gHiresFontRangeCount = 0; void InitHiresFonts() { @@ -41,50 +46,48 @@ void InitHiresFonts() gHiresDigitsTexture = GR_CreateRGBATexture(width, height, data); } free(data); + data = NULL; } } // init font2 if(!gHiresFontTexture) { + gHiresFontRangeCount = 0; + + int width, height, bpp; int x, y; int size; FILE* fp; - sprintf(namebuffer, "%s%s", gDataFolder, "GFX\\HQ\\ariblk.ttf"); + sprintf(namebuffer, "%s%s", gDataFolder, "GFX\\HQ\\font2.fn2"); fp = fopen(namebuffer, "rb"); if (fp) { - // read whole file - fseek(fp, 0, SEEK_END); - size = ftell(fp); - fseek(fp, 0, SEEK_SET); - data = (u_char*)malloc(size); - fread(data, 1, size, fp); - fclose(fp); + int i; - // gen font - u_char* tmpBitmap = (u_char*)malloc(HIRES_FONT_SIZE_W * HIRES_FONT_SIZE_H); - u_int* bitmapRGBA = (u_int*)malloc(HIRES_FONT_SIZE_W * HIRES_FONT_SIZE_H * 4); + // read fn2 step by step + OUT_FN2HEADER fn2hdr; + fread(&fn2hdr, sizeof(fn2hdr), 1, fp); - stbtt_pack_context pc; - - stbtt_PackBegin(&pc, tmpBitmap, HIRES_FONT_SIZE_W, HIRES_FONT_SIZE_H, 0, 1, NULL); - stbtt_PackSetOversampling(&pc, 2, 2); - stbtt_PackFontRange(&pc, data, 0, 40.0f, 32, 224, gSTBCharData); - stbtt_PackEnd(&pc); - - for (x = 0; x < HIRES_FONT_SIZE_W; ++x) + gHiresFontRangeCount = fn2hdr.range_count; + for (i = 0; i < fn2hdr.range_count; ++i) { - for (y = 0; y < HIRES_FONT_SIZE_H; ++y) - { - bitmapRGBA[x + y * HIRES_FONT_SIZE_W] = tmpBitmap[x + y * HIRES_FONT_SIZE_W] << 24 | 0xffffff; - } + fread(&gHiresFontRanges[i], sizeof(gHiresFontRanges[i]), 1, fp); + fread(gHiresFontCharData[i], sizeof(OUT_FN2INFO), gHiresFontRanges[i].count, fp); } - gHiresFontTexture = GR_CreateRGBATexture(HIRES_FONT_SIZE_W, HIRES_FONT_SIZE_H, (u_char*)bitmapRGBA); - free(bitmapRGBA); - free(tmpBitmap); + fclose(fp); + } + + // load TGA file + sprintf(namebuffer, "%s%s", gDataFolder, "GFX\\HQ\\font2.tga"); + if (LoadTGAImage(namebuffer, &data, width, height, bpp)) + { + if (bpp == 32) + { + gHiresFontTexture = GR_CreateRGBATexture(HIRES_FONT_SIZE_W, HIRES_FONT_SIZE_H, data); + } free(data); } } @@ -131,13 +134,14 @@ void SetHiresDigitsTexture(int enabled) current->primptr += sizeof(DR_PSYX_TEX); } -void GetHiresBakedQuad(int char_index, float* xpos, float* ypos, stbtt_aligned_quad* q) +void GetHiresBakedQuad(int char_index, float* xpos, float* ypos, FONT_QUAD* q) { float ipw = 1.0f / (float)HIRES_FONT_SIZE_W; float iph = 1.0f / (float)HIRES_FONT_SIZE_H; - const stbtt_packedchar* b = gSTBCharData + char_index; - float scale = 0.45f; + const OUT_FN2INFO* b = gHiresFontCharData[0] + char_index - gHiresFontRanges[0].start; + + float scale = 0.275f; float s_x = b->x1 - b->x0; float s_y = b->y1 - b->y0; @@ -176,8 +180,8 @@ int StrighWidthHires(char* string) float fx, fy; fx = 0.0f; fy = 0.0f; - stbtt_aligned_quad q; - GetHiresBakedQuad(chr - 32, &fx, &fy, &q); + FONT_QUAD q; + GetHiresBakedQuad(chr, &fx, &fy, &q); width += fx; } return width; @@ -223,8 +227,8 @@ int PrintStringHires(char* string, int x, int y) float fx, fy; fx = width; fy = y; - stbtt_aligned_quad q; - GetHiresBakedQuad(chr - 32, &fx, &fy, &q); + FONT_QUAD q; + GetHiresBakedQuad(chr, &fx, &fy, &q); fontFT4 = (POLY_FT4*)current->primptr; diff --git a/src_rebuild/Game/C/pres.h b/src_rebuild/Game/C/pres.h index 821814c0..4c95890f 100644 --- a/src_rebuild/Game/C/pres.h +++ b/src_rebuild/Game/C/pres.h @@ -3,12 +3,9 @@ struct OUT_FONTINFO { - u_char x; - u_char y; - char offx; - char offy; - u_char width; - u_char height; + u_char x, y; + char offx, offy; + u_char width, height; u_short pad; }; diff --git a/src_rebuild/premake5.lua b/src_rebuild/premake5.lua index ab56f11b..1b4a17ce 100644 --- a/src_rebuild/premake5.lua +++ b/src_rebuild/premake5.lua @@ -3,6 +3,8 @@ require "premake_modules/usage" require "premake_modules/emscripten" +IS_ANDROID = (_ACTION == "androidndk") + ------------------------------------------ newoption { @@ -58,6 +60,7 @@ workspace "REDRIVER2" "-Wno-parentheses", "-Wno-format", } + linkoptions { "-s TOTAL_MEMORY=1073741824", "-s USE_SDL=2", @@ -80,6 +83,51 @@ workspace "REDRIVER2" "{COPY} " .. WEBSHELL_PATH .. "/lsfs.js %{cfg.buildtarget.directory}" } + elseif IS_ANDROID then + system "android" + shortcommands "On" + + platforms { + "android-arm", "android-arm64" + } + + disablewarnings { + "c++11-narrowing", + "constant-conversion", + "writable-strings", + "unused-value", + "switch", + "shift-op-parentheses", + "parentheses", + "format", + } + + buildoptions { + "-fpermissive", + "-fexceptions", + "-pthread", + } + + linkoptions { + "--no-undefined", + "-fexceptions", + "-pthread", + + "-mfloat-abi=softfp", -- force NEON to be used + "-mfpu=neon" + } + + filter "platforms:*-x86" + architecture "x86" + + filter "platforms:*-x86_64" + architecture "x86_64" + + filter "platforms:*-arm" + architecture "arm" + + filter "platforms:*-arm64" + architecture "arm64" else platforms { "x86" } --, "x86_64" } end @@ -137,6 +185,9 @@ end -- Psy-Cross layer include "premake5_psycross.lua" +-- font tool +include "premake5_font_tool.lua" + -- game iteslf project "REDRIVER2" kind "WindowedApp" @@ -175,7 +226,6 @@ project "REDRIVER2" "utils/**.cpp", "utils/**.c", "redriver2_psxpc.cpp", - "DebugOverlay.cpp", } filter "platforms:emscripten" diff --git a/src_rebuild/premake5_font_tool.lua b/src_rebuild/premake5_font_tool.lua new file mode 100644 index 00000000..823c24df --- /dev/null +++ b/src_rebuild/premake5_font_tool.lua @@ -0,0 +1,33 @@ +-- Font generator tool +project "FontTool" + kind "ConsoleApp" + language "C++" + targetdir "bin/%{cfg.buildcfg}" + + files { + "tools/font_tool/**.h", + "tools/font_tool/**.H", + "tools/font_tool/**.c", + "tools/font_tool/**.C", + "tools/font_tool/**.cpp", + "tools/font_tool/**.CPP", + "utils/stb_truetype.*", + "utils/targa.*", + } + + defines { } + + includedirs { + "utils", + "PsyCross/include/psx" + } + + filter "system:Windows" + defines { "_WINDOWS" } + + filter "configurations:Release" + optimize "Speed" + + filter "configurations:Release_dev" + optimize "Speed" + diff --git a/src_rebuild/tools/font_tool/font_tool_main.cpp b/src_rebuild/tools/font_tool/font_tool_main.cpp new file mode 100644 index 00000000..407d2916 --- /dev/null +++ b/src_rebuild/tools/font_tool/font_tool_main.cpp @@ -0,0 +1,156 @@ +#include +#include +#include +#include +#include + +#define STB_TRUETYPE_IMPLEMENTATION +#include "stb_truetype.h" +#include "targa.h" + +#include "hqfont.h" + +struct FN2RangeInfo +{ + OUT_FN2RANGE hdr; + OUT_FN2INFO* chars; +}; + +static FN2RangeInfo fontRanges[4]; +static int fontRangeCount = 0; + +void Usage() +{ + printf("example: FontTool -i -o \n\nAdditional arguments:"); + printf("\t-r : add range of characters"); +} + +int main(int argc, char** argv) +{ + if (argc < 2) + { + Usage(); + return 0; + } + + { + FN2RangeInfo& firstRange = fontRanges[0]; + + firstRange.hdr.start = 32; + firstRange.hdr.count = 224; + firstRange.chars = new OUT_FN2INFO[firstRange.hdr.count]; + ++fontRangeCount; + } + + const char* inputFilename = nullptr; + const char* outpitFilename = nullptr; + + for (int i = 0; i < argc; ++i) + { + if (!strcmp(argv[i], "-i") && i + 1 < argc) + { + inputFilename = argv[i+1]; + } + else if (!strcmp(argv[i], "-o") && i + 1 < argc) + { + outpitFilename = argv[i + 1]; + } + else if (!strcmp(argv[i], "-r") && i + 2 < argc) + { + FN2RangeInfo& newRange = fontRanges[fontRangeCount]; + + newRange.hdr.start = atoi(argv[i + 1]); + newRange.hdr.count = atoi(argv[i + 2]); + newRange.chars = new OUT_FN2INFO[newRange.hdr.count]; + ++fontRangeCount; + } + } + + if (!inputFilename) + { + Usage(); + return 0; + } + + if (!outpitFilename) + { + Usage(); + return 0; + } + + FILE* fp = fopen(inputFilename, "rb"); + if (!fp) + { + printf("Cannot open %s\n", inputFilename); + return -1; + } + + // read whole file + fseek(fp, 0, SEEK_END); + const long size = ftell(fp); + fseek(fp, 0, SEEK_SET); + u_char* data = (u_char*)malloc(size); + fread(data, 1, size, fp); + fclose(fp); + + // gen font + u_char* tmpBitmap = (u_char*)malloc(HIRES_FONT_SIZE_W * HIRES_FONT_SIZE_H); + u_int* bitmapRGBA = (u_int*)malloc(HIRES_FONT_SIZE_W * HIRES_FONT_SIZE_H * 4); + + stbtt_pack_context pc; + stbtt_PackBegin(&pc, tmpBitmap, HIRES_FONT_SIZE_W, HIRES_FONT_SIZE_H, 0, 2, NULL); + stbtt_PackSetOversampling(&pc, 1, 1); + stbtt_PackSetSkipMissingCodepoints(&pc, 1); + + for (int i = 0; i < fontRangeCount; ++i) + { + FN2RangeInfo& range = fontRanges[i]; + stbtt_PackFontRange(&pc, data, 0, 65.0f, range.hdr.start, range.hdr.count, (stbtt_packedchar*)range.chars); + } + + stbtt_PackEnd(&pc); + + for (int x = 0; x < HIRES_FONT_SIZE_W; ++x) + { + for (int y = 0; y < HIRES_FONT_SIZE_H; ++y) + { + bitmapRGBA[x + y * HIRES_FONT_SIZE_W] = tmpBitmap[x + y * HIRES_FONT_SIZE_W] << 24 | 0xffffff; + } + } + + { + char tgaFileName[256]; + strcpy(tgaFileName, outpitFilename); + strcat(tgaFileName, ".tga"); + + SaveTGAImage(tgaFileName, (u_char*)bitmapRGBA, HIRES_FONT_SIZE_W, HIRES_FONT_SIZE_H, 32); + } + + { + char fntFileName[256]; + strcpy(fntFileName, outpitFilename); + strcat(fntFileName, ".fn2"); + + FILE* fntFp = fopen(fntFileName, "wb"); + if (fntFp) + { + OUT_FN2HEADER fn2hdr; + fn2hdr.version = FN2_VERSION; + fn2hdr.range_count = fontRangeCount; + fwrite(&fn2hdr, sizeof(fn2hdr), 1, fntFp); + + for (int i = 0; i < fontRangeCount; ++i) + { + FN2RangeInfo& range = fontRanges[i]; + fwrite(&range.hdr, sizeof(OUT_FN2RANGE), 1, fntFp); + fwrite(range.chars, sizeof(OUT_FN2INFO), range.hdr.count, fntFp); + + delete[] range.chars; + } + } + } + + free(bitmapRGBA); + free(tmpBitmap); + free(data); +} \ No newline at end of file diff --git a/src_rebuild/DebugOverlay.cpp b/src_rebuild/utils/DebugOverlay.cpp similarity index 95% rename from src_rebuild/DebugOverlay.cpp rename to src_rebuild/utils/DebugOverlay.cpp index 61ab2deb..a8b67c53 100644 --- a/src_rebuild/DebugOverlay.cpp +++ b/src_rebuild/utils/DebugOverlay.cpp @@ -1,21 +1,19 @@ -#include "Game/driver2.h" - -#include "Game/C/mission.h" -#include "Game/C/convert.h" -#include "Game/C/camera.h" -#include "Game/C/dr2roads.h" -#include "Game/C/system.h" -#include "Game/C/pres.h" -#include "Game/C/spool.h" -#include "Game/C/cars.h" -#include "Game/C/draw.h" -#include "Game/C/players.h" -#include "Game/C/glaunch.h" - -#include +#include "driver2.h" +#include "C/mission.h" +#include "C/convert.h" +#include "C/camera.h" +#include "C/dr2roads.h" +#include "C/system.h" +#include "C/pres.h" +#include "C/spool.h" +#include "C/cars.h" +#include "C/draw.h" +#include "C/players.h" +#include "C/glaunch.h" #include "C/felony.h" +#include int gDisplayDrawStats = 0; @@ -243,7 +241,7 @@ void Debug_Line2D(SXYPAIR& pointA, SXYPAIR& pointB, CVECTOR& color) line->g0 = color.g; line->b0 = color.b; -#if defined(USE_PGXP) && defined(USE_EXTENDED_PRIM_POINTERS) +#if USE_PGXP && USE_EXTENDED_PRIM_POINTERS line->pgxp_index = 0xFFFF; #endif diff --git a/src_rebuild/utils/hqfont.h b/src_rebuild/utils/hqfont.h new file mode 100644 index 00000000..0c125096 --- /dev/null +++ b/src_rebuild/utils/hqfont.h @@ -0,0 +1,27 @@ +#ifndef HQFONT_H +#define HQFONT_H + +#define FN2_VERSION 1 +#define HIRES_FONT_SIZE_W 768 +#define HIRES_FONT_SIZE_H 768 + +struct OUT_FN2INFO +{ + u_short x0, y0, x1, y1; + float xoff, yoff, xadvance; + float xoff2, yoff2; +}; + +struct OUT_FN2RANGE +{ + u_short start; + u_short count; +}; + +struct OUT_FN2HEADER +{ + u_short version; + u_short range_count; +}; + +#endif // HQFONT_H \ No newline at end of file diff --git a/src_rebuild/utils/targa.cpp b/src_rebuild/utils/targa.cpp index 82dbacf6..ffecd628 100644 --- a/src_rebuild/utils/targa.cpp +++ b/src_rebuild/utils/targa.cpp @@ -177,5 +177,61 @@ bool LoadTGAImage(const char* filename, u_char** data, int& width, int& height, free(tempBuffer); free(fBuffer); + return true; +} + +bool SaveTGAImage(const char* filename, u_char* data, int width, int height, int bpp) +{ + TGAHeader tgaHeader; + + // Initialize the Targa header + tgaHeader.descriptionlen = 0; + tgaHeader.cmaptype = 0; + tgaHeader.imagetype = 2; + tgaHeader.cmapstart = 0; + tgaHeader.cmapentries = 0; + tgaHeader.cmapbits = 0; + tgaHeader.xoffset = 0; + tgaHeader.yoffset = 0; + tgaHeader.width = width; + tgaHeader.height = height; + tgaHeader.bpp = bpp; + tgaHeader.attrib = 0; + + int imageSize = width * height * (bpp / 8); + + FILE* fp = fopen(filename, "wb"); + if (!fp) + return false; + + // Write the header + fwrite(&tgaHeader, sizeof(TGAHeader), 1, fp); + + // Write the image data + u_char* src = data + (bpp / 8) * width * (height - 1); + + switch (bpp) + { + case 32: + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + u_char pixel[4]; + pixel[0] = src[2]; + pixel[1] = src[1]; + pixel[2] = src[0]; + pixel[3] = src[3]; + + fwrite(pixel, sizeof(pixel), 1, fp); + src += 4; + } + src -= 8 * width; + } + break; + } + + fclose(fp); + return true; } \ No newline at end of file diff --git a/src_rebuild/utils/targa.h b/src_rebuild/utils/targa.h index 0183663a..8190f903 100644 --- a/src_rebuild/utils/targa.h +++ b/src_rebuild/utils/targa.h @@ -24,5 +24,6 @@ struct TGAHeader #pragma pack (pop) bool LoadTGAImage(const char* filename, u_char** data, int& width, int& height, int& bpp); +bool SaveTGAImage(const char* filename, u_char* data, int width, int height, int bpp); #endif // TARGA_H \ No newline at end of file From e78eed458a0182ffbccffa626fd97f85466536cb Mon Sep 17 00:00:00 2001 From: Ilya Shurumov Date: Sun, 18 Dec 2022 23:42:44 +0600 Subject: [PATCH 04/20] - replace ttf with fn2 and tga fonts --- data/DRIVER2/GFX/HQ/ariblk.ttf | Bin 167592 -> 0 bytes data/DRIVER2/GFX/HQ/fefont.fn2 | Bin 0 -> 8468 bytes data/DRIVER2/GFX/HQ/fefont.tga | Bin 0 -> 2359314 bytes data/DRIVER2/GFX/HQ/font2.fn2 | Bin 0 -> 8468 bytes data/DRIVER2/GFX/HQ/font2.tga | Bin 0 -> 2359314 bytes 5 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 data/DRIVER2/GFX/HQ/ariblk.ttf create mode 100644 data/DRIVER2/GFX/HQ/fefont.fn2 create mode 100644 data/DRIVER2/GFX/HQ/fefont.tga create mode 100644 data/DRIVER2/GFX/HQ/font2.fn2 create mode 100644 data/DRIVER2/GFX/HQ/font2.tga diff --git a/data/DRIVER2/GFX/HQ/ariblk.ttf b/data/DRIVER2/GFX/HQ/ariblk.ttf deleted file mode 100644 index e7ae345aa00723d337f807324143f8548f11b235..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 167592 zcmcG%34EMadFXv!X=XJ0zVG`;qnVL3k~Na7ktK~~%XYjZvJ*RT5<5{s5&{V%kc1Lq zmNda(Z3Bc}+MBk}QlM03DS_U$X-iw6EbZ<7BO#%5yDhz?ExljM5`X{ayfc==bs_ov zzVCT`-uJxcJm)#jdA766SfdQ3RFs=Vo!Y&zZ*So>QJ)&BZYh=d#NOR&dsNlpQbW5p z!OHGEa(LrgfAE2;cz=^p?SI(2acuS2uHnzCp?mIx$hR&#y0QK~$LoJdso*IHIuCD5 zwExcgGry^n@%OYpb>quU-+9<;yG^NkW|Xq+zVX#}=Wjf8+bfiM$PLbuH{bb^m)-D3 zH~qF!_uotX`(JYUt~*s+72xM_+WTK}`+YYLJz2Y7sdqf3jC(e3*?if(3FC<#eculG z&)ss<>CL}=Q*9YqysOz;C~kL ztcL8gaeeIeJ8nGv+U3HUQV)MoDZBS&r|-RU#9^<~9vUkDvYYNco&3O0T&{-Rc8d4) zm!E#wP5(0S`z19L`Zi;J^PP9xb@%yU^<(gRM)2=^GNAkWNlse z`q$p~KUc5!E&jVo*(p%!1D8KZd!_!&{p`$hcYXgYo-_6j^Xk(0Qb9ZWm%snxN_l?& zxx1db+jHhZjno1bo0M?>SGA~aP*ydh{Axm7ORtyP-miwK9k#r5_)XNL&nh1kmYeT^efBi-tTI{+>RdX<<+vve|O0Gndc4}CHt3$UUN#R z|NhLM(__{88Bp?S$ks<6f^(fdq+V-LYSOx{7OhvRSw?!}NJhPPXkHx~&Zs*{M=W=# zbJRaD1TLwmpYzH9|0wAfr5$OVR44UFSCXzFN&Vh_yVpYFrKH!9Znu0x?X!OK{C8~g z@HDU9Lpn`*pY`|EyJ+*6?L+E1(qr`hLEcM}=lSlDx2kuNe=q4;a37UtzujKmCwLcH zR=YZXp64)Wi1H$I9vYfI{~ewa^nbrao&Pp`$r$#L?kDXh$r#qb@$;1O9|Py?(1*^y zub+Q2@_C))`}NXpefX{F0md`UbB_0W$PdBiFnJewEAp#AGl@(e=NY5_8-=faIxS-! zj7j+K)0X~!FkRr0I?b!epEBU_uSw5QKH%*K+ulRn#p$iX)B0U#zJj!Z9el#}CH0Wt z*=|+~l16??mFeT>HSKkE19JTYJeDjURw2gm0OaQo=2kvXdMlZ+;T~oG~ zv{Up4FW;uWjwEEeM-nt182+}J5V=b`w~eVx%gi)I zyiW5hik*m!2;cB{K%O!V>K^6&ei<9-eq<@Si;{Bi{nP!l$M#|M-{9psaQ6w{1KQ9z zP1*jzll;22{|~Fz4v(v`et-KedcM#0q*~YSra!JjOZ;-(KCeDvJ+9tN{@w7epUBUA z?on^1|Myb&V;7!Js~zO8rA+9*Pkd$Y9Pr0;Li-L+t5S2|ix1p0cv7!rGk9KzU4s~Q ziKial9r*ba{`jZJ?0&V!gB+374VH7p2+zat{oWsVK1SJNBY$e#W_?mUY55X<{io_D zhW<>wQ4;x&@w}69fB7O=JzuszATM~is$a7Kb zgy%>4@-9*TKJaxrX-g7a1SvCR|3>QW(lOMO`wz$;o(49z1G$TSo+s~%-ldOwB$i4% zlQD}u4(HH~X`}lj9w5Ut+LXZEXFRBE@b{d?Rq6@b?<(8K2bIk-#4|?vEmB3 zA5}x7$40&a&Y!DyTTdzXKn9HEu?zD01oMc{+Je8=>$s$2khHPgaY0@p#|yHet;{tO zLUSN1+t;CahkD4)(~(k-*)3|?{z1y7NY|-dj@>-F$^vgPhW(arA`?IUewp&}z78Eb zvb@at3zSJJVUM3tDfIqk<^hQddh9&)94oRC8?vWp!~AG{P`wITca1!zUN!PD^(x!A zvX2l)EdQa~?i%?L`R8;zT({nWe-J-tw;vkQq9c*9_=7#hDs6%`;0O=W2YB~bUZLJS z{2PjS+qB^ye2RStu1(ehdM-HsZQ9-9{2lce{(m*LE%Eg*>3Y(eD0?q4_;r>q4P`A~ zG7RfS&;O(4{}`XOest)Jc~kIvfQk$vYu48S-NT-IqbANL5iqd zwlS5kD`QgP5c5)rbcB=v=LWHH(U;hs#Ch#oMb?!8=IblflyzAxS#RUH&ht)n(i&6C z);;Q=^=|U4AuT7=VQhBRx{1v^%sTZNwPHQOIwPQVNQ z)&=Z&>HPOBUm(_f_55#+oKROoqfFar-S!^xKd#;)_?JxZr1=q^`f2D3_yIie{5PK7 z3%m$F7boH4;shVh>qEvXNyf>zN##Kw7e95q;0Uga`zh9mUpW6g`Yw`uCNJvIk?`~7 zB(fT$emhfczuTADfLCN^?I$fmk>emCPm$>$J#Rc0jZI{IaT1vilE{9Lv|iAImVaOG zmiN*>c|B%uHLu@PSIf9W=ekW_=WNA}Y8i_hME7NNoz^-1*@7cB|Wd z4jRxJd05#kpTwt3Jw2-1JPc14+w6dM=}+txniqJtL-U=)=--Cc|EAxXN-!TkYMmlY zsQn|4^SlFD9Z-+r^L5gN^(pxVN#cQ&>zKfEy#KDB+IPi&Uq~|NGjk38qw>T8;=sk} zZM^@`q+@`@fgh4AUuXStaXm4ExN-aN@9=z*#3{n_>MzFa=Or!?bMzkWhdr6w*ej?X zleqMQeMtP0WXYOO@FbRPr-xYQV>=i8S?2yL)oVyz>*thnB&*uQnHk%rI)e6W2H=vL z39gG@4A(_91B@T?1pNgyZ~;Gr%>Nfv7t_Bu|08L83)^Ez{wVCA=SN{|*Nbe-i?SEP z()n!~m&ggFkS_1j3>rq#V|c=zs1!sm(d54@az3wSo5!dTjT#=tY7Y1Rf9+k&$2J>9 zBW}be4Wnfkfv6EQ>gMR0f?YRUQ6rs8SB-`-S&ol2Y=+G!w!rXG+lbqYT-1cLfHY~? z1SH4sqLk%w{kn9cp^JqQ(BRd?ECMaStlhpx4O`TRMALL`l%r#yH;gD)-nuQC=8elp zdn4(hVZgs(#2e@(V!#HZCtq+4;#s$n=MHGA9C8SXapMGOMvJ@lH2ZV9rf!!6dD~rWq8yRsqhvmu3@W=(QSR`wA0QM1w!!qI+agya9 z$;HDmY#Fg>q!I3*TU^q@$~EE~p^AEGOp@|G(23c`e3!h<0iKg$mjh;`!0xcakpp^k zp^ID=$hcfKm(4ajOb?DB>5=+jn~N^&cA*Q3fMokHVzH0dZNqdhVi#}Zx~s0CmWgOXgDioOq8jZhCF z6?R>zsSnUxPS|pcz~0D^#bI-}Y)%e?g$)rn8K)_HI~gbM2*wno4SDOFl}=#`;X9pD z;IzAFjF>zg7!=9y>J|+`K<;+YsKf1Xxg8FVu!gLiBX*dlO24`w>2%pqr|4EX5((-$ zs|)^wX*;s;!M9mX;}-?Gp-^_BeE-@47 zoW7krrO1vh#ISKOQLgX?(g+<;2eW;2yWOP)?G&TD2&AVU0oDPGkg-@ugMtB%Vj;Q$ zCbX>x6Ox>EhdbiXalmeOyN0b85uFcj3rGt~TMs7VbXsZRa*7FxMPfJ(>#!Bi&<(62 zJiEm$FT?@uQ6o|>18_Q>+f=oXFM6e=-R6Wo%D2142&KT`w8N3pjbDml_~#Z!aJy}8 zi35n;F(f_G?XXRFfg6CH1TGSyU7T)YSo~LKi68#NZTb7GxgBo16T#ShJ~v~aB{vVU zcHqC7l-&hMkJs&SIKARNn5K({A`f}kMnt1-p#xFGhdwM8H(BY`4S&M4W7uZ*k04jK zm^kk*3Uos^ZbUfJ{$X>t#f(MXR?)@)Ow-^Emc7Ws$?&aO1lYYG(RY8g>c1goiDDNT zY8)NP(35~LsxxSe=71Kr)-oZ~EEu5ZdW|B@#Lj5SyYwRRklsbW+P9@tdUt3Wg$occ z5K*r5B_WCq$VqUQ=Gd1A8tJ?2HnHUkAiecLI=vKJz?C>)wc54`2yZ4JEUAzBzY*rwq*trAUcC?@km}rWbBSG zZ546RmKpd0JiilZiAcb6Lx5>Z#L48s)Qr2xBI2Sr zKzOy=q8__21WPcAn3=ycF+B$Dt~8Tt5CI^AT!L}6Mqtf%xa37;_O93e;(2gtjbHzf`@{C+f}UEk&K3K0m%9TXyh z*XQv%oj%?$PaWYg4?TtvyJ*zyAs`b!P_3*kEFKvx%MlO!3Dc}S905CW1x2h}H+{i3 z-H-rmCmbPRcyM|o4#?0jSvUfO=7k(O_7fyA5!5L5gLO-{^v!IAvib`rQ5y-~Y2Nn+ zd5EPj*a7GoUiwd&@&u$Apsin{>UwTwJF&BVBUz71tf8TF4i|zYYNbs0lVT7s5K*qU zyo{3=Et*BYLRqxo5kV8ZO>fp*a1#gYgLHZ+kY$PnS;A;{@4vHF9st5J0|b+eKz|@^ zhtrpIak$Pr@AP>rtbk2!F}h15%93`ENNAj2EvdD7BpXZ&t2#Xjs-0OdL1$b)TKu`@*F^f8fpd_KERRvu#O z!_p(&TI@cVme?=Q0K){Ni#|B5=!1odlTZsbI6j{beh?64^klWk6ML35F8oV>@WTaD zBW?)^Bq?wasRv|nd32xjIfNlt@*!_b7wZvXP?Aei(RZ8Gyqs2%1UI)XHmMKLd|tN$ zW?;`bj1_vkc8|})sKsXyzsK!G_{1=m+e;Qq6b3cSh;4w5X3TwvjsTCMq{`#+(b#5l z27^A>K^GMH85txH6H;@s6mSOuKEK-?KpGPEy|@_>SEPl(ibh#Yc(E3gfMSt=k3#9y z=amb=TI|lS1G$2tqu-@W^}j6B4Sg7<&+kR_@Zk1gu&jrWyw<*O0>GOIupE>i$)Igo z1S2+WQ94}Weee#i;$kvedEni&DrqeqAWGE3)02itlXs~iMpCG?>@j1Z@NJ^#dW|Aw zVrM2j>4hG2?{tYni%)A6GY4uLmG!d@$cR$bb>N!;S#+e)bwCzDivsk9MC@6EIA9;7 z(>@G}^mDLO!S&dZumzEAiUyS02ZSXRGF#~q*n|-mw&+j0bsQkPdht4VCJx9LO_1r8 zNl1ejBDR4Cp#&V#jp4ZQb38*M6P-b~`sIZg36DY-QZKFHTqBt`t%dD(TDt6B==&hR zw54n8^aV#=KkHx2L3HDnIN97zf^b`n= zpUKhV67QGjA#s2wt|brnx8m+tlE;PDNgM!=Bn8Z}+JrP=;(&7`?RN-6u;fSHn6AyL zi3ve2X=Gl5IN-91B)FNENqz9<$3|cV_SmJl?OvbV>-REhk)e(QK8bQNRG-^N96&I# z0K$yeV(ZPiY_*wYTwa&YC$jOm{e*0r%@qpyVTYF70?3+(im2or%ku<-{(##PLK;L7 zmyd={NC?=SqEXD#=OlihTJ&MH`caGY>i5ZofH-Q3I*}_VRDky)z^xnlF-?EKN62Qr zbo(U^h{hxiXj($kG!1gF9%2>dVbF3q16#xay2abvY${mY3J<*DQn(dV<#ijxQWz{C z!Zgce@B$KcwJF)WdSwJjq@+QrB^F2t(-t5lfEW4_X=sS05Emt)N-&0`+eRgGolJ1J z7|Nv#c3{p2CHxTmn&_f>1dZ!Bgu@HaH|ihu7km~OhpL66Tpl(HiBi1iv@yi3&;yW z-G%+IZl#{)A~KC+-ei0iy^8HRywLYk9FWOK3h+xf@&#Nnal-{H;^f{yz!8vmE_2?n z^hmc>M?eQB8MxQ$5&cLPeb5f?5YN+b036O?;ivE0axkg=kWt~e0cKD76MkGiB*cLM zcERz96i6HxkhQVabB$yIPGJa^WHOaFVCy@$jsw!jyyW;xE|*Ot!3{A|Wl|p?1+WpA zfj!r-&ExR;nIV0QS{xYhdp&+y5w8e`WJko{_5d9%$Gwe*}!4M02e<=OzhmoNlN zA>@q&M{JrHl;qM>^nDNqJT}%Ma`Wk8lllNH6!f`Ad>+_im*#W&gLp=OQRAtIkl8ng z@Wp?9L9$>vVU`%d@dz{}7V<=NPJ(nGD6$E9Lp0{}A{Gn54!R(KL>L()5ED}K1Q~fG z8jARQQCaLE>mUs!PVgXhibmO0==B2PlhuVSgjzV%bA*C&Ay})^lVr^i3bD>1YDvo% z3|`$ZgiD3O0YuL_*%!iK<+#9W*ApzXgl2zAV&&-f$0SHHXgQtXxPmiF8UKaZO7O)c ziD@oB3m|#j2C)=9JUwZc<-F^R#7J#QBZN@#d~rK-Fj7A#5sff=>jI2JK5@~#(F&#^xt@xuS81e<(xX$+Bo;bHSU>~H@OTl2v zqL(moU}>JEP%P^{6A+eE$Ol5YKqeQNT0Oo<*{>*vorp*to>^3EhZ~t*B>(_EZ!l>0 z2EAcSB8WW&{SgW|%VlEK4T#R5k3{5!!znz930CT*aWELvNal@B%r@pLExoQFGkuui zh)h;e;0t)+C>ZgI!|GW+f|Ca$5m!XwDz@&oNRM=Db46r%$|ju#!2q2FrHejz@fV-l zh6jl|dBKT9BJhLvQzi=oyFC4j3b%+tPuxAoSVKW(WX#ROApjl~^s+jZV{H?di#(2U z#4QZLQUrP9Z$u&?1|_+qk$K5+vRvK~kp#DZt}v+&kRoBf2WDW;YZ>vof?+%(#Hfk7 zh|nJNhY@}di|~iYf{DVQh8a19Z2}K#U_|HghPA&cSkmRalTg+htwACmq_N zIJNSPpd@63vUx+u;#@?0X{kY6Ks30`qFFAK1(>!VB0w|o{5~RBQoUUwc4ihLQ;8lD zpExohF48^ks2C=Ea*Bd-0wC~_2n#dHXa`SW5GAH-bWZ>^ha>*5*Bkcgk8H%AHHZWD zK|1Zj_SXx@U5Ep6tSbkW{liQas^;*xBP^+q&m*KvWC9~h=z;iHP*Lvo`{NNpg@=8v z9lIL<^RYOw#QA_f9CrA_{#ZC12#4_5P@F=dj^8avejG+N$@aM9Wm)Qr`8o5WUK)qP zVJYu}jBSwTDceJL7`zz8@vx4wtY^ak4!>ivwWP1JRFa^;}TcdM};iXBi)X; zCNfnTO#n|2>2+YYr9jPc$}6c4Zsb@&{1O-!$sk=cby4zuO*+eH%G%*&)c zc#FqEK1aw8dw#1urHi_+hjjijoBrg&`W|MON;1iG|F4ek_h4 z9gT@>VmLQya`-cu7-0lm_``uDM1l~26k}#75K5)u$xtYbG?>HuQ9tK~$e;FzISxry z6H%W(h7wRL!;dG-UgI&jn8QZg{=8Sdej|~U#xDkfx?vp4j3=V9N@Ajn%aI_*1pyal zz`}=K=3xgg1sCWz6Lz6Qy98=#*`tVdeck}GRe;%wrt;=vw(>@zWFV#i#``nI1s~aMQg(U2ti(o9A35gQXWE80d6OmXn zn@eRPksQ)s4htrT{DDv`M0-p+1<7PGk_ZHoC;`PX{8U=^>PaQ!La;0q%YNjVVp&Dt z8CdNLdWLnw6qcDzCwvGW&rOLL2SxJCXTpbG=3xgg1sCYJ5Orfzj-ZnZww#WDR1qP} z*$N(b3kPC&S}XxeL1L+Z_G!_e1VttmK#EMtf)EM?iMaxCf;9k!U3=I!4QkWa6A;vw4;i!;|ql{N#cN? zeXdis&wXIm%lIQQ;7BMQcd-UY#p989EJDgqh@Xdig2cv4H*#exy(&F#))GVp^NQAXEJmpqx*BFv20FuQ%0 zN^!=Th=*dHn1|*hDTpx74#;xY>kE3?nSd|^OX)}eG4oFogOXg*$h_nbPp*(tB*86? z{Druuqn zaDwIziEKn0aDcyrWzmL9VhZTE6!)M+r!3fD6YJJUfk?#31Q(Z>j(jx!~NCKc81)+qvGJ%JNNSU}8!OJiz z%7YOnl_)0$0!N{uTrotMg;F$NiOVD=PRW`poX$j3EX=~<&D$Uj*atE0OMz@zG|1tO zoN1WHY`koH9>S6e`9Mepj7Vkdkz_cQ@5B}5{zxRB<}-|-xDxZv0CXe@$7R5=NGj!K z4UlCnO(kNaJcS&fNBm~EV&en4D=%%Cks{$Nx{!Kl%tSGu$&*el4so(Q^rs@pWR~K5 z3g)CBmW*=fmC7@liCv+vyepAN<@5eLn-B;4sDxE|gq*{lPhiY35nPH13Xm@P5W!z! zK}RBz2;)w&4bA8C@Z*k!DWfNsN1n`U5=;tFcKfX7Qj8U(gg4=(IY|m)LHu+8erF)$ z?c_tk5G>_zBK*ze(!`)7m!_icoCE1A;u1-4OGc&Aq&`5)XA@y}A_996n=9c@<^1Vf zhEYdE;3;=1kwy3^EFzI5>rSvTP3@+b0Q#u1UcXaf#dx@O)wn5oPwo(P$C-9R!u=91%s@+h)*uM#GzwhqDeB6Mocl*ajf0KNxd** ztVzlk5(~2|v{~ZDG)B0&&1TNT-(q*{*2dc!5(#`5ry)=e%Der>_d64Hx%V+>*k~xYCDHg3#5KqP6 zC|!t#T`ZeLj|EpUnJN?l1vv?b`ol?^^hmdkKq1KjIxdn+rII2h>7ox&7gKN0k&Gt8 zaj?ND6bk87)DsU=Mo%t}Jehgp(Rj2d>u;85DaHy?(wFqn+!sgHsc4+__JFL5PYlD} z`9eq-f~7oX4sLhY?b5`cB$qTYFZ0tx4-yhda5FEH`rxgQONL>lP)J2>u4Evc4`lKg zMjaJ_r#z`-4&lo@p3IU36NO>l;b_n&Y=@)BJr?B%Ets zj+ZgvcnVE&DiDumlj&5YS|}%zRiwcND5~Q?JT20S2EqkMYV(W|5uzv-2^5NEuZ5gk z$#B9Eh&IB=wEz#{7a0fQx?uqyE0(fBgwG6KkT?(($-A`o%XW`#T9g~PC^{ZZ`7kOM z*2DgQPdZ!@csaF-yIE$XS=_~jjrx}>QDF#{ z%E%kj^|&=Ly>CWl7cP#E^_6goB)DaDl}UYoRw-p--b@1a5+hh)t`sVi3yeA;0?&DK znG(Vm|IHN1f*FQckqui-a?I|5L^2UhhZ2Q&u_Ur7r7AS`dK1lN8FtV`B9|IPm#Hk8 z3=u*_<$7-n%14W%ngTt23Pl%F%;L|iV6BAkF1hKaIr z&0K(0ikk(S2Q~vCaa1AaC(Jrk*dtQi52jLA+mFOoAd43t*PBSduCoBU9Q3 z3wSahC}7fyR1Zp0EKT!JmuMN!C*ujW%F=r(o@23>iZKmjr94Kwjwe0wSQZ2fq*BSs z{tkR|VTPcYx_ReIU(YL?Cz4LrD;&$l(!99!|HITbua`$MCviTTE|vW0QhKyh%9aZF zY@tpeC+q2mAf?kB@__EGOP=j%Iyst7#-v^vm)M?egZS(ATRK2KQcf3(qZHRm30)P* zmNI;yrd&@az3CWSz@oQMDAntcy2RCVBv}}d9_iK{sTZ>FBu6-Y_?D%3nmInr&Gyvj2*le86o#_is5uuLXIku@odgVfGy=R$xJ3m%qyqTiE=F=uj0>u zc)z%q1VttmAg#-@G!S6yxt#XF3X}jas1uOtehGzTfUYS>mFb%$GN`^>s+5aoa>-O8 zU6k@<&X-ANeCcEn1Pr8JFXB>+CZ0`7Ku#0UHF~m`%4f#v`BBz78S& zmMI$e+=mluK1%7ohl(OT4G2przUY;fxmb;vzCnMjD$HdmC{*(tg4bHPw2!GXo6hB0zH+(RYQ~*)BcO zttZwhGjSH=l&4xP(^*xz=tItjA0<8ITsd9HWwYS4S}phq7Sfc_lP@UGa*Z(-aucFT zCjTm9tyOd7a5+r#a3LcF1vWzivV7f*H_Lb zlHgX+RVMWTT5G(Vh8ft)Ieg_;uJ#&h|+gc{oCV(E!oKHF%N>X}>aGShd@S)>QHBzZE=wL1Yo19f} zP=QAmivCnFRV(H*c@}tuYz+gh)$uS!VS>1T%os(P&-22eSDlW{9Mf>}VeM@l)x~rYp&8#_vy|+-#

~YFrKMgPGf_x+A0*HX@;qgGm>4gNj!shCuA4@b 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

#f+9>9hVr9e*P); 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 w*&ZLZDJNSKSY|{yTpWeRyKf&|Y8UO$Q diff --git a/data/DRIVER2/GFX/HQ/fefont.fn2 b/data/DRIVER2/GFX/HQ/fefont.fn2 new file mode 100644 index 0000000000000000000000000000000000000000..9349c4d8e3f6b0c882dc4e09201e69f788b950b2 GIT binary patch literal 8468 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 Jz)_k5{{izQt%U#p literal 0 HcmV?d00001 diff --git a/data/DRIVER2/GFX/HQ/font2.fn2 b/data/DRIVER2/GFX/HQ/font2.fn2 new file mode 100644 index 0000000000000000000000000000000000000000..313289bec08f752156edac51301bc08eb546809e GIT binary patch literal 8468 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 ZWd>IMW_bU~ieAIJUR^%?#>ta!`yZpFm@WVS literal 0 HcmV?d00001 diff --git a/data/DRIVER2/GFX/HQ/font2.tga b/data/DRIVER2/GFX/HQ/font2.tga new file mode 100644 index 0000000000000000000000000000000000000000..1bfe5c96798d4042d03537fceabe2c030ab30ef9 GIT binary patch literal 2359314 zcmeF43EXehy#KEzlt!rtg-oGRiKIzMG9}3nm6UlNGCSRFH;F&)CG$-g5*d>lMJGds z$Pgl>4yub(n$w~FpHH5p)jE6c_1*h7JkN8^d%a$t*4}%4*LO|tz4v$T{d+q9_HWDm z+rQHC|F-;w|8~<&HzDQ#24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H z24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaN zU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS z00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H24DaNU;qYS00v+H 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 literal 0 HcmV?d00001 From 4a4b632f1e7e60a2f6836700263674bee361fab6 Mon Sep 17 00:00:00 2001 From: Ilya Shurumov Date: Mon, 19 Dec 2022 13:33:32 +0600 Subject: [PATCH 05/20] - Frontend Hires font --- src_rebuild/Game/Frontend/FEmain.c | 306 ++++++++++++++++++++++++++--- 1 file changed, 284 insertions(+), 22 deletions(-) diff --git a/src_rebuild/Game/Frontend/FEmain.c b/src_rebuild/Game/Frontend/FEmain.c index 724fd993..3906f5cf 100644 --- a/src_rebuild/Game/Frontend/FEmain.c +++ b/src_rebuild/Game/Frontend/FEmain.c @@ -22,6 +22,258 @@ #include "C/spool.h" #include "C/state.h" +#ifndef PSX + +#include "PsyX/PsyX_render.h" +#include "../utils/targa.h" +#include "../utils/hqfont.h" + +#pragma optimize("", off) + +#define HIRES_FONTS + +struct FEFONT_QUAD +{ + float x0, y0, s0, t0; // top-left + float x1, y1, s1, t1; // bottom-right +}; + +TextureID gHiresFEFontTexture = 0; +OUT_FN2RANGE gHiresFEFontRanges[4]; +OUT_FN2INFO gHiresFEFontCharData[4][224]; +int gHiresFEFontRangeCount = 0; + +void InitHiresFEFont() +{ + char namebuffer[64]; + u_char* data; + + // init font2 + if (!gHiresFEFontTexture) + { + gHiresFEFontRangeCount = 0; + + int width, height, bpp; + int x, y; + int size; + FILE* fp; + sprintf(namebuffer, "%s%s", gDataFolder, "GFX\\HQ\\fefont.fn2"); + + fp = fopen(namebuffer, "rb"); + if (fp) + { + int i; + + // read fn2 step by step + OUT_FN2HEADER fn2hdr; + fread(&fn2hdr, sizeof(fn2hdr), 1, fp); + + gHiresFEFontRangeCount = fn2hdr.range_count; + for (i = 0; i < fn2hdr.range_count; ++i) + { + fread(&gHiresFEFontRanges[i], sizeof(gHiresFEFontRanges[i]), 1, fp); + fread(gHiresFEFontCharData[i], sizeof(OUT_FN2INFO), gHiresFEFontRanges[i].count, fp); + } + + fclose(fp); + } + + // load TGA file + sprintf(namebuffer, "%s%s", gDataFolder, "GFX\\HQ\\fefont.tga"); + if (LoadTGAImage(namebuffer, &data, width, height, bpp)) + { + if (bpp == 32) + { + gHiresFEFontTexture = GR_CreateRGBATexture(HIRES_FONT_SIZE_W, HIRES_FONT_SIZE_H, data); + } + free(data); + } + } +} + +void FEGetHiresBakedQuad(int char_index, float scale, float* xpos, float* ypos, FEFONT_QUAD* q) +{ + float ipw = 1.0f / (float)HIRES_FONT_SIZE_W; + float iph = 1.0f / (float)HIRES_FONT_SIZE_H; + + const OUT_FN2INFO* b = gHiresFEFontCharData[0] + char_index - gHiresFEFontRanges[0].start; + + float fscale = 0.5f * scale; + + float s_x = b->x1 - b->x0; + float s_y = b->y1 - b->y0; + + q->x0 = *xpos + b->xoff * fscale; + q->y0 = *ypos + b->yoff * fscale; + q->x1 = (b->xoff2 - b->xoff) * fscale; + q->y1 = (b->yoff2 - b->yoff) * fscale; + + q->s0 = b->x0 * 255.0f * ipw; + q->t0 = b->y0 * 255.0f * iph; + q->s1 = s_x * 255.0f * ipw; + q->t1 = s_y * 255.0f * iph; + + q->y0 += 32.0f; + + *xpos += b->xadvance * fscale; +} + +void SetHiresFEFontTexture(int enabled) +{ + if (gHiresFEFontTexture == 0) + { + return; + } + + DR_PSYX_TEX* tex = (DR_PSYX_TEX*)current->primptr; + if (enabled) + SetPsyXTexture(tex, gHiresFEFontTexture, 255, 255); + else + SetPsyXTexture(tex, 0, 0, 0); + + addPrim(current->ot + 1, tex); + current->primptr += sizeof(DR_PSYX_TEX); +} + +int FEStringWidthHires(char* string) +{ + char* pString = string; + u_char c = 0; + + int w = 0; + + while ((c = *pString++) != 0) + { + float fx, fy; + fx = 0; + fy = 0; + FEFONT_QUAD q; + FEGetHiresBakedQuad(c, 1.0f, &fx, &fy, &q); + + w += fx; + } + + return w; +} + +int FEPrintStringSizedHires(char* string, int x, int y, int scale, int transparent, int r, int g, int b) +{ + if (current == NULL || string == NULL) + return -1; + + POLY_FT4* shadow; + POLY_FT4* font; + u_char let; + int w; + int h; + + SetHiresFEFontTexture(0); + font = (POLY_FT4*)current->primptr; + + while ((let = *string++) != 0) + { + if (let == '\n') + continue; + + float fx, fy; + fx = x; + fy = y; + FEFONT_QUAD q; + FEGetHiresBakedQuad(let, scale / 4096.0f, &fx, &fy, &q); + + setPolyFT4(font); + setSemiTrans(font, 1); + + setRGB0(font, r, g, b); + setUVWH(font, q.s0, q.t0, q.s1, q.t1); + setXYWH(font, q.x0, q.y0, q.x1, q.y1); + + font->clut = 0; + font->tpage = 0; + + addPrim(current->ot + 1, font); + shadow = font + 1; + + // add shadow poly + memcpy(shadow, font, sizeof(POLY_FT4)); + setRGB0(shadow, 10, 10, 10); + setXYWH(shadow, q.x0 + 1.0f, q.y0 + 1.0f, q.x1, q.y1); + + addPrim(current->ot + 1, shadow); + font += 2; + + // make room for next character + x += fx - x; + } + + // set tail + current->primptr = (char*)font; + SetHiresFEFontTexture(1); + + return x; +} + +int FEPrintStringHires(char* string, float x, float y, int justification, int r, int g, int b) +{ + POLY_FT4* shadow; + POLY_FT4* font; + u_char let; + + if (justification & 4) + { + x -= FEStringWidthHires(string); + } + + SetHiresFEFontTexture(0); + font = (POLY_FT4*)current->primptr; + + int counter = 0; + + while ((let = *string++) != 0) + { + float fx, fy; + fx = x; + fy = y; + FEFONT_QUAD q; + FEGetHiresBakedQuad(let, 1.0f, &fx, &fy, &q); + + setPolyFT4(font); + setSemiTrans(font, 1); + + setRGB0(font, r, g, b); + setUVWH(font, q.s0, q.t0, q.s1, q.t1); + setXYWH(font, q.x0, q.y0, q.x1, q.y1); + + font->clut = 0; + font->tpage = 0; + + addPrim(current->ot + 1, font); + shadow = font + 1; + + // add shadow poly + memcpy(shadow, font, sizeof(POLY_FT4)); + setRGB0(shadow, 10, 10, 10); + setXYWH(shadow, q.x0 + 1.0f, q.y0 + 1.0f, q.x1, q.y1); + + addPrim(current->ot + 1, shadow); + font += 2; + + // add space for next character + x += fx - x; + + if (++counter >= 32) + break; + } + + // set tail + current->primptr = (char *)font; + + SetHiresFEFontTexture(1); + + return x; +} + +#endif // PSX struct PSXBUTTON { @@ -703,7 +955,7 @@ void DisplayOnScreenText(void) text = "Incompatible controller in Port 1"; } - FEPrintStringSized(text, 40, 400, 0xc00, transparent, 64, 64, 64); + FEPrintStringSized(text, 40, 400, 3072, transparent, 64, 64, 64); } else { @@ -717,14 +969,14 @@ void DisplayOnScreenText(void) strcat(ScreenTitle, ScreenNames[i]); } - FEPrintStringSized(ScreenTitle, 40, 400, 0xc00, 1, 64, 64, 64); + FEPrintStringSized(ScreenTitle, 40, 400, 3072, 1, 64, 64, 64); } if (iScreenSelect == SCREEN_CUTSCENE) { text = GET_MISSION_TXT(CutSceneNames[cutSelection + CutAmountsTotal[currCity]]); - FEPrintStringSized(text, 100, 226, 0xc00, 1, 64, 64, 64); + FEPrintStringSized(text, 100, 226, 3072, 1, 64, 64, 64); } } } @@ -1554,6 +1806,9 @@ void SetFEDrawMode(void) void InitFrontend(void) { InitCdIcon(); +#ifdef HIRES_FONTS + InitHiresFEFont(); +#endif ResetGraph(1); SetDispMask(0); @@ -1706,9 +1961,15 @@ int FEStringWidth(char* string) { char* pString = string; u_char c = 0; - int w = 0; +#ifdef HIRES_FONTS + if (gHiresFEFontTexture) + { + return FEStringWidthHires(string); + } +#endif + while ((c = *pString++) != 0) { if (c == ' ') @@ -1726,30 +1987,24 @@ int FEPrintString(char *string, int x, int y, int justification, int r, int g, i if (current == NULL || string == NULL) return -1; +#ifdef HIRES_FONTS + if (gHiresFEFontTexture) + { + return FEPrintStringHires(string, x, y, justification, r, g, b); + } +#endif + FE_CHARDATA *pFontInfo; SPRT *font; u_char let; - font = (SPRT *)current->primptr; - if (justification & 4) { - char *pString = string; - u_char c = 0; - - int w = 0; - - while ((c = *pString++) != 0) - { - if (c == ' ') - w += 4; - else - w += feFont.CharInfo[c].w; - } - - x -= w; + x -= FEStringWidth(string); } + font = (SPRT*)current->primptr; + int counter = 0; while ((let = *string++) != 0) @@ -1807,6 +2062,13 @@ int FEPrintStringSized(char *string, int x, int y, int scale, int transparent, i if (current == NULL || string == NULL) return -1; +#ifdef HIRES_FONTS + if (gHiresFEFontTexture) + { + return FEPrintStringSizedHires(string, x, y, scale, transparent, r, g, b); + } +#endif + POLY_FT4 *font; FE_CHARDATA *pFontInfo; u_char let; @@ -1875,10 +2137,10 @@ int CentreScreen(int bSetup) char text[32]; sprintf(text, "X1: %d, Y1: %d", current->disp.screen.x, current->disp.screen.y); - FEPrintStringSized(text, 25, 50, 0xC00, 0, 128, 0, 0); + FEPrintStringSized(text, 25, 50, 3072, 0, 128, 0, 0); sprintf(text, "X2: %d, Y2: %d", last->disp.screen.x, last->disp.screen.y); - FEPrintStringSized(text, 25, 75, 0xC00, 0, 128, 0, 0); + FEPrintStringSized(text, 25, 75, 3072, 0, 128, 0, 0); #endif if (feNewPad & MPAD_CROSS) From 4338b0da4bf176a42e0a28b663b810960a9af710 Mon Sep 17 00:00:00 2001 From: Ilya Shurumov Date: Mon, 19 Dec 2022 13:34:50 +0600 Subject: [PATCH 06/20] - version bump --- appveyor.yml | 2 +- src_rebuild/Game/version.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 50e4b803..876327b5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 7.6.{build} +version: 7.8.{build} branches: only: diff --git a/src_rebuild/Game/version.h b/src_rebuild/Game/version.h index 49edbe37..9087f4a4 100644 --- a/src_rebuild/Game/version.h +++ b/src_rebuild/Game/version.h @@ -1,9 +1,9 @@ #ifndef GAME_VERSION_N -#define GAME_VERSION_N "7.6" +#define GAME_VERSION_N "7.8" #endif #ifndef GAME_VERSION_RES -#define GAME_VERSION_RES 7,6 +#define GAME_VERSION_RES 7,8 #endif #define GAME_TITLE "REDRIVER2" From 58a7e4a2f6cdcadf3231b8b22826808603925830 Mon Sep 17 00:00:00 2001 From: Ilya Shurumov Date: Sat, 18 Feb 2023 12:41:13 +0600 Subject: [PATCH 07/20] - overrideContent to work with car models, cosmetics and dentings --- src_rebuild/Game/C/cosmetic.c | 4 +++- src_rebuild/Game/C/denting.c | 12 ++++++++---- src_rebuild/Game/C/models.c | 12 ++++++++++-- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src_rebuild/Game/C/cosmetic.c b/src_rebuild/Game/C/cosmetic.c index 6e7f6399..be54e745 100644 --- a/src_rebuild/Game/C/cosmetic.c +++ b/src_rebuild/Game/C/cosmetic.c @@ -68,7 +68,9 @@ void ProcessCosmeticsLump(char *lump_ptr, int lump_size) car_cosmetics[i] = *(CAR_COSMETICS*)((u_char*)lump_ptr + offset); #ifndef PSX - LoadCustomCarCosmetics(&car_cosmetics[i], model); + extern int gContentOverride; + if(gContentOverride) + LoadCustomCarCosmetics(&car_cosmetics[i], model); #endif FixCarCos(&car_cosmetics[i], model); } diff --git a/src_rebuild/Game/C/denting.c b/src_rebuild/Game/C/denting.c index c2662940..308b124c 100644 --- a/src_rebuild/Game/C/denting.c +++ b/src_rebuild/Game/C/denting.c @@ -457,11 +457,15 @@ void ProcessDentLump(char *lump_ptr, int lump_size) offset = *(int *)(lump_ptr + model * 4); mem = (u_char*)lump_ptr; #ifndef PSX - char* newDenting = LoadCarDentingFromFile(NULL, model); - if(newDenting) + extern int gContentOverride; + if (gContentOverride) { - mem = (u_char*)newDenting; - offset = 0; + char* newDenting = LoadCarDentingFromFile(NULL, model); + if (newDenting) + { + mem = (u_char*)newDenting; + offset = 0; + } } #endif diff --git a/src_rebuild/Game/C/models.c b/src_rebuild/Game/C/models.c index 71572e85..7357d89d 100644 --- a/src_rebuild/Game/C/models.c +++ b/src_rebuild/Game/C/models.c @@ -314,10 +314,18 @@ MODEL* GetCarModel(char *src, char **dest, int KeepNormals, int modelNumber, int char* mem; #ifndef PSX - mem = LoadCarModelFromFile(NULL, modelNumber, type); + extern int gContentOverride; + if (gContentOverride) + { + mem = LoadCarModelFromFile(NULL, modelNumber, type); - if (!mem) // fallback to lump + if (!mem) // fallback to lump + mem = src; + } + else + { mem = src; + } #else mem = src; #endif From 92822bc52ad26f42cb20603b637663532194c927 Mon Sep 17 00:00:00 2001 From: Ilya Shurumov Date: Sat, 18 Feb 2023 12:48:03 +0600 Subject: [PATCH 08/20] - DMODEL -> MDL --- src_rebuild/Game/C/models.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src_rebuild/Game/C/models.c b/src_rebuild/Game/C/models.c index 7357d89d..0b8bd543 100644 --- a/src_rebuild/Game/C/models.c +++ b/src_rebuild/Game/C/models.c @@ -292,7 +292,7 @@ char* LoadCarModelFromFile(char* dest, int modelNumber, int type) char* mem; char filename[64]; - sprintf(filename, "LEVELS\\%s\\CARMODEL_%d_%s.DMODEL", LevelNames[GameLevel], modelNumber, CarModelTypeNames[type-1]); + sprintf(filename, "LEVELS\\%s\\CARMODEL_%d_%s.MDL", LevelNames[GameLevel], modelNumber, CarModelTypeNames[type-1]); if(FileExists(filename)) { mem = (char*)(dest ? dest : (_other_buffer + modelNumber * 0x10000 + (type-1) * 0x4000)); From 4ae670dcf82c016f402694a3fff56d511cd80ea2 Mon Sep 17 00:00:00 2001 From: Ilya Date: Sat, 1 Apr 2023 02:41:24 +0600 Subject: [PATCH 09/20] - Fix incorrectly generated flatpak --- .appveyor/Build.sh | 14 +++++++------- .appveyor/Install.sh | 8 ++++---- .../io.github.opendriver2.Redriver2.appdata.xml | 4 ++-- .flatpak/start.sh | 2 +- io.github.opendriver.redriver2.yaml | 8 ++++---- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.appveyor/Build.sh b/.appveyor/Build.sh index 23d3fe07..56fd62d5 100755 --- a/.appveyor/Build.sh +++ b/.appveyor/Build.sh @@ -1,21 +1,22 @@ #!/usr/bin/env bash set -ex -# Creating flatpak directories -mkdir -p "${APPVEYOR_BUILD_FOLDER}/.flatpak/lib" "${APPVEYOR_BUILD_FOLDER}/.flatpak/data" "${APPVEYOR_BUILD_FOLDER}/.flatpak/bin" - +# Configure cd "$APPVEYOR_BUILD_FOLDER/src_rebuild" - ./premake5 gmake2 - cd project_gmake2_linux +# Build for config in debug_x86 release_x86 release_dev_x86 do make config=$config -j$(nproc) done -find ${APPVEYOR_BUILD_FOLDER}/src_rebuild/bin -name 'REDRIVER2*' -exec cp -t ${APPVEYOR_BUILD_FOLDER}/.flatpak/bin {} + +cd ${APPVEYOR_BUILD_FOLDER} + +# Creating flatpak directories +mkdir -p "${APPVEYOR_BUILD_FOLDER}/.flatpak/lib" "${APPVEYOR_BUILD_FOLDER}/.flatpak/data" "${APPVEYOR_BUILD_FOLDER}/.flatpak/bin" +find ${APPVEYOR_BUILD_FOLDER}/src_rebuild/bin/Release -name 'REDRIVER2*' -exec cp -t ${APPVEYOR_BUILD_FOLDER}/.flatpak/bin {} + # Copy missing libraries in the runtime for lib in libjpeg libopenal libsndio libbsd @@ -24,7 +25,6 @@ do done cp -r "${APPVEYOR_BUILD_FOLDER}/data" "${APPVEYOR_BUILD_FOLDER}/.flatpak/" -cd ${APPVEYOR_BUILD_FOLDER} # Editing metadatas with the current version export APPVEYOR_BUILD_DATE=$(date "+%Y-%m-%d") diff --git a/.appveyor/Install.sh b/.appveyor/Install.sh index afe2e976..7ca639f0 100755 --- a/.appveyor/Install.sh +++ b/.appveyor/Install.sh @@ -26,7 +26,7 @@ export XDG_DATA_DIRS="/var/lib/flatpak/exports/share:${HOME}/.local/share/flatpa flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo # Adding Platform/SDK for the Linux flatpak release -flatpak --user install flathub org.freedesktop.Platform/x86_64/20.08 -y -flatpak --user install flathub org.freedesktop.Sdk/x86_64/20.08 -y -flatpak --user install flathub org.freedesktop.Sdk.Compat.i386/x86_64/20.08 -y -flatpak --user install flathub org.freedesktop.Sdk.Extension.toolchain-i386/x86_64/20.08 -y +flatpak --user install flathub org.freedesktop.Platform/x86_64/22.08 -y +flatpak --user install flathub org.freedesktop.Sdk/x86_64/22.08 -y +flatpak --user install flathub org.freedesktop.Sdk.Compat.i386/x86_64/22.08 -y +flatpak --user install flathub org.freedesktop.Sdk.Extension.toolchain-i386/x86_64/22.08 -y diff --git a/.flatpak/io.github.opendriver2.Redriver2.appdata.xml b/.flatpak/io.github.opendriver2.Redriver2.appdata.xml index 52950d8f..c08e84b9 100644 --- a/.flatpak/io.github.opendriver2.Redriver2.appdata.xml +++ b/.flatpak/io.github.opendriver2.Redriver2.appdata.xml @@ -4,9 +4,9 @@ MIT MIT REDRIVER2 -

Driver 2 Playstation game reverse engineering effort + Driver 2 - Back On The Streets / The Wheelman Is Back -

Driver 2 Playstation game reverse engineering effort

+

Reverse-Engineered version of Driver 2. https://opendriver2.github.io

Game diff --git a/.flatpak/start.sh b/.flatpak/start.sh index d268502f..7d0019d4 100644 --- a/.flatpak/start.sh +++ b/.flatpak/start.sh @@ -13,7 +13,7 @@ function importDefaultData { } if [ ! -d /var/data/DRIVER2 ]; then - zenity --error --no-wrap --text="`printf "DRIVER2 files are missing! Add the folder in:\n ${HOME}/.var/io.github.opendriver2.Redriver2/data"`" + zenity --error --no-wrap --text="`printf "DRIVER2 files are missing! Please provide DRIVER2 folder in:\n ${HOME}/.var/app/io.github.opendriver2.Redriver2/data"`" exit 0 fi diff --git a/io.github.opendriver.redriver2.yaml b/io.github.opendriver.redriver2.yaml index 2fa0acf1..97052a7e 100644 --- a/io.github.opendriver.redriver2.yaml +++ b/io.github.opendriver.redriver2.yaml @@ -1,7 +1,7 @@ --- app-id: io.github.opendriver2.Redriver2 runtime: org.freedesktop.Platform -runtime-version: '20.08' +runtime-version: '22.08' rename-icon: 'icon' sdk: org.freedesktop.Sdk command: start.sh @@ -17,14 +17,14 @@ finish-args: add-extensions: org.freedesktop.Platform.Compat.i386: directory: lib/i386-linux-gnu - version: '20.08' + version: '22.08' org.freedesktop.Platform.Compat.i386.Debug: directory: lib/debug/lib/i386-linux-gnu - version: '20.08' + version: '22.08' no-autodownload: true org.freedesktop.Platform.GL32: directory: lib/i386-linux-gnu/GL - version: '20.08' + version: '22.08' subdirectories: true no-autodownload: true autodelete: false From 3c4fe2c0d0fec0d9752abe7a1fd87464e164ed9d Mon Sep 17 00:00:00 2001 From: SoapyMan Date: Sun, 2 Apr 2023 01:24:03 +0600 Subject: [PATCH 10/20] - try to fixup flatpak yml --- io.github.opendriver.redriver2.yaml | 34 +++++++++++++++++++---------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/io.github.opendriver.redriver2.yaml b/io.github.opendriver.redriver2.yaml index 97052a7e..ba473be4 100644 --- a/io.github.opendriver.redriver2.yaml +++ b/io.github.opendriver.redriver2.yaml @@ -1,9 +1,11 @@ ---- app-id: io.github.opendriver2.Redriver2 runtime: org.freedesktop.Platform -runtime-version: '22.08' -rename-icon: 'icon' +runtime-version: &runtime-version '22.08' +x-gl-version: &gl-version '1.4' +x-gl-versions: &gl-versions 22.08;22.08-extra;1.4 sdk: org.freedesktop.Sdk +separate-locales: false +rename-icon: 'icon' command: start.sh finish-args: - "--socket=x11" @@ -14,38 +16,47 @@ finish-args: - "--persist=." - "--allow=multiarch" - "--env=SDL_DYNAMIC_API=/app/lib/i386-linux-gnu/libSDL2-2.0.so.0" + add-extensions: org.freedesktop.Platform.Compat.i386: directory: lib/i386-linux-gnu - version: '22.08' + version: *runtime-version + org.freedesktop.Platform.Compat.i386.Debug: directory: lib/debug/lib/i386-linux-gnu - version: '22.08' + version: *runtime-version no-autodownload: true + org.freedesktop.Platform.GL32: directory: lib/i386-linux-gnu/GL - version: '22.08' + version: *gl-version + versions: *gl-versions subdirectories: true no-autodownload: true autodelete: false add-ld-path: lib - merge-dirs: vulkan/icd.d;glvnd/egl_vendor.d + merge-dirs: vulkan/icd.d;glvnd/egl_vendor.d;OpenCL/vendors;lib/dri;lib/d3d;vulkan/explicit_layer.d;vulkan/implicit_layer.d download-if: active-gl-driver enable-if: active-gl-driver + sdk-extensions: - org.freedesktop.Sdk.Compat.i386 - org.freedesktop.Sdk.Extension.toolchain-i386 + build-options: - prepend-pkg-config-path: "/app/lib32/pkgconfig:/usr/lib/i386-linux-gnu/pkgconfig" - ldflags: "-L/app/lib32" - append-path: "/usr/lib/sdk/toolchain-i386/bin" + prepend-pkg-config-path: /app/lib32/pkgconfig:/usr/lib/i386-linux-gnu/pkgconfig + ldflags: -L/app/lib32 + prepend-path: /usr/lib/sdk/toolchain-i386/bin env: CC: i686-unknown-linux-gnu-gcc CXX: i686-unknown-linux-gnu-g++ - libdir: "/app/lib32" + libdir: /app/lib32 + cleanup: - "/include" + modules: + - name: ld-i386 buildsystem: simple build-commands: @@ -55,6 +66,7 @@ modules: - type: shell commands: - echo "/app/lib32" > ld.so.conf + - name: game buildsystem: simple build-commands: From ade9c48828e3247329f7f9db6b30ba1b98fc1f00 Mon Sep 17 00:00:00 2001 From: SoapyMan Date: Sun, 2 Apr 2023 01:43:54 +0600 Subject: [PATCH 11/20] - add ld.so.conf for flatpak - more stuff to setup 32 bit platform --- .flatpak/ld.so.conf | 5 +++++ io.github.opendriver.redriver2.yaml | 21 +++++++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 .flatpak/ld.so.conf diff --git a/.flatpak/ld.so.conf b/.flatpak/ld.so.conf new file mode 100644 index 00000000..76daf657 --- /dev/null +++ b/.flatpak/ld.so.conf @@ -0,0 +1,5 @@ +# We just make any GL32 extension have higher priority +include /run/flatpak/ld.so.conf.d/app-*-org.freedesktop.Platform.GL32.*.conf +/app/lib32 +/app/lib/i386-linux-gnu +/lib64 \ No newline at end of file diff --git a/io.github.opendriver.redriver2.yaml b/io.github.opendriver.redriver2.yaml index ba473be4..91a6d90f 100644 --- a/io.github.opendriver.redriver2.yaml +++ b/io.github.opendriver.redriver2.yaml @@ -57,15 +57,24 @@ cleanup: modules: -- name: ld-i386 +- name: platform-bootstrap buildsystem: simple build-commands: - - mkdir -p /app/lib/i386-linux-gnu /app/lib/debug/lib/i386-linux-gnu - - install -Dm644 -t /app/etc ld.so.conf + - | + set -e + mkdir -p /app/bin + mkdir -p /app/lib/i386-linux-gnu + mkdir -p /app/lib/debug/lib/i386-linux-gnu + mkdir -p /app/lib/i386-linux-gnu/GL + cp /usr/bin/addr2line /app/bin/ + cp /usr/lib/x86_64-linux-gnu/libbfd-*.so /app/lib/ + install -Dm644 -t /app/etc ld.so.conf + mkdir -p /app/links/lib + ln -srv /app/lib /app/links/lib/x86_64-linux-gnu + ln -srv /app/lib32 /app/links/lib/i386-linux-gnu sources: - - type: shell - commands: - - echo "/app/lib32" > ld.so.conf + - type: dir + path: .flatpak - name: game buildsystem: simple From 0ad72866fff55bc832d48c704ca762dd44b43080 Mon Sep 17 00:00:00 2001 From: SoapyMan Date: Sun, 9 Apr 2023 20:43:18 +0600 Subject: [PATCH 12/20] - add Dockerfile for local builds --- Dockerfile | 39 +++++++++++++++++++++++++++++++++++++++ dockerbuild.sh | 5 +++++ 2 files changed, 44 insertions(+) create mode 100644 Dockerfile create mode 100755 dockerbuild.sh diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..f6462a3b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,39 @@ +FROM fedora:37 +LABEL Description="Build environment" + +ENV HOME /root + +SHELL ["/bin/bash", "-c"] + +RUN dnf update -y && \ + dnf groupinstall -y 'Development Tools' && \ + dnf install -y make gcc gcc-c++ \ + libjpeg-turbo-devel.i686 \ + glibc-devel.i686 \ + SDL2-devel.i686 \ + openal-soft-devel.i686 \ + flatpak flatpak-builder + +ENV APPVEYOR_BUILD_FOLDER=/src + +# Setting XDG_DATA_DIRS environement variable for flatpak +ENV XDG_DATA_DIRS="/var/lib/flatpak/exports/share:${HOME}/.local/share/flatpak/exports/share:$XDG_DATA_DIRS" + +# Adding the flathub repo +RUN flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo + +# Adding Platform/SDK for the Linux flatpak release +RUN flatpak --user install flathub org.freedesktop.Platform/x86_64/22.08 -y +RUN flatpak --user install flathub org.freedesktop.Sdk/x86_64/22.08 -y +RUN flatpak --user install flathub org.freedesktop.Sdk.Compat.i386/x86_64/22.08 -y +RUN flatpak --user install flathub org.freedesktop.Sdk.Extension.toolchain-i386/x86_64/22.08 -y + +WORKDIR /src + +CMD ["/bin/bash"] + +# Building example: +# docker build -t builder/multiarch_build:1.0 -f Dockerfile . + +# Running example: +# docker run -it --privileged=true --rm --name=builder --mount type=bind,source=${PWD},target=/src builder/multiarch_build:1.0 bash diff --git a/dockerbuild.sh b/dockerbuild.sh new file mode 100755 index 00000000..6158a1a1 --- /dev/null +++ b/dockerbuild.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -ex + +docker build -t builder/multiarch_build:1.0 -f Dockerfile . +docker run -it --privileged=true --rm --name=builder --mount type=bind,source=${PWD},target=/src builder/multiarch_build:1.0 ./.appveyor/Build.sh From 14a2333b70dd786945961d5f248da0dad894eb1d Mon Sep 17 00:00:00 2001 From: SoapyMan Date: Sun, 9 Apr 2023 20:54:44 +0600 Subject: [PATCH 13/20] - fix hires fonts support for Linux --- src_rebuild/Game/C/pres.c | 5 ++++- src_rebuild/Game/Frontend/FEmain.c | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src_rebuild/Game/C/pres.c b/src_rebuild/Game/C/pres.c index 0d42e2d3..83ea3639 100644 --- a/src_rebuild/Game/C/pres.c +++ b/src_rebuild/Game/C/pres.c @@ -36,7 +36,7 @@ void InitHiresFonts() { int width, height, bpp; - sprintf(namebuffer, "%s%s", gDataFolder, "GFX\\HQ\\DIGITS.TGA"); + sprintf(namebuffer, "%s%s", gDataFolder, "GFX\\HQ\\digits.tga"); FS_FixPathSlashes(namebuffer); if (LoadTGAImage(namebuffer, &data, width, height, bpp)) @@ -60,6 +60,7 @@ void InitHiresFonts() int size; FILE* fp; sprintf(namebuffer, "%s%s", gDataFolder, "GFX\\HQ\\font2.fn2"); + FS_FixPathSlashes(namebuffer); fp = fopen(namebuffer, "rb"); if (fp) @@ -82,6 +83,8 @@ void InitHiresFonts() // load TGA file sprintf(namebuffer, "%s%s", gDataFolder, "GFX\\HQ\\font2.tga"); + FS_FixPathSlashes(namebuffer); + if (LoadTGAImage(namebuffer, &data, width, height, bpp)) { if (bpp == 32) diff --git a/src_rebuild/Game/Frontend/FEmain.c b/src_rebuild/Game/Frontend/FEmain.c index 3906f5cf..6352f64f 100644 --- a/src_rebuild/Game/Frontend/FEmain.c +++ b/src_rebuild/Game/Frontend/FEmain.c @@ -58,6 +58,7 @@ void InitHiresFEFont() int size; FILE* fp; sprintf(namebuffer, "%s%s", gDataFolder, "GFX\\HQ\\fefont.fn2"); + FS_FixPathSlashes(namebuffer); fp = fopen(namebuffer, "rb"); if (fp) @@ -80,6 +81,8 @@ void InitHiresFEFont() // load TGA file sprintf(namebuffer, "%s%s", gDataFolder, "GFX\\HQ\\fefont.tga"); + FS_FixPathSlashes(namebuffer); + if (LoadTGAImage(namebuffer, &data, width, height, bpp)) { if (bpp == 32) From 5da47de37e8a9c2f34efcd61093430858417c822 Mon Sep 17 00:00:00 2001 From: SoapyMan Date: Sun, 9 Apr 2023 20:57:35 +0600 Subject: [PATCH 14/20] - some code style & refactoring for car denting code --- src_rebuild/Game/C/cars.c | 27 ++++++++----- src_rebuild/Game/C/denting.c | 78 ++++++++++-------------------------- 2 files changed, 38 insertions(+), 67 deletions(-) diff --git a/src_rebuild/Game/C/cars.c b/src_rebuild/Game/C/cars.c index 7617c959..22f5dc82 100644 --- a/src_rebuild/Game/C/cars.c +++ b/src_rebuild/Game/C/cars.c @@ -260,7 +260,7 @@ void plotCarPolyGT3(int numTris, CAR_POLY *src, SVECTOR *vlist, SVECTOR *nlist, ofse = pg->damageLevel[src->originalindex]; - *(u_int*)&prim->u0 = (src->clut_uv0 & 0xffffU | pg->pciv_clut[palette + (src->clut_uv0 >> 0x10)] << 0x10) + ofse; + *(u_int*)&prim->u0 = pg->pciv_clut[(src->clut_uv0 >> 0x10) + palette] << 0x10 | (src->clut_uv0 & 0xffff) + ofse; *(u_int*)&prim->u1 = src->tpage_uv1 + ofse; *(u_int*)&prim->u2 = src->uv3_uv2 + ofse; @@ -331,7 +331,7 @@ void plotCarPolyGT3Lit(int numTris, CAR_POLY* src, SVECTOR* vlist, SVECTOR* nlis ofse = pg->damageLevel[src->originalindex]; - *(u_int*)&prim->u0 = (src->clut_uv0 & 0xffffU | pg->pciv_clut[palette + (src->clut_uv0 >> 0x10)] << 0x10) + ofse; + *(u_int*)&prim->u0 = pg->pciv_clut[(src->clut_uv0 >> 0x10) + palette] << 0x10 | (src->clut_uv0 & 0xffff) + ofse; *(u_int*)&prim->u1 = src->tpage_uv1 + ofse; *(u_int*)&prim->u2 = src->uv3_uv2 + ofse; @@ -408,7 +408,7 @@ void plotCarPolyGT3nolight(int numTris, CAR_POLY *src, SVECTOR *vlist, plotCarGl ofse = pg->damageLevel[src->originalindex]; - *(u_int*)&prim->u0 = (src->clut_uv0 & 0xffffU | pg->pciv_clut[palette + (src->clut_uv0 >> 0x10)] << 0x10) + ofse; + *(u_int*)&prim->u0 = pg->pciv_clut[(src->clut_uv0 >> 0x10) + palette] << 0x10 | (src->clut_uv0 & 0xffff) + ofse; *(u_int*)&prim->u1 = src->tpage_uv1 + ofse; *(u_int*)&prim->u2 = src->uv3_uv2 + ofse; @@ -971,7 +971,8 @@ void buildNewCars(void) // [D] [T] void buildNewCarFromModel(CAR_MODEL *car, MODEL *model, int first) { - u_char ptype, clut; + ushort clut; + u_char ptype, carid; u_char *polyList; CAR_POLY *cp; @@ -1080,12 +1081,14 @@ void buildNewCarFromModel(CAR_MODEL *car, MODEL *model, int first) { POLYGT3* pgt3 = (POLYGT3*)polyList; - clut = GetCarPalIndex(pgt3->texture_set); - civ_clut[clut][pgt3->texture_id][0] = texture_cluts[pgt3->texture_set][pgt3->texture_id]; + carid = GetCarPalIndex(pgt3->texture_set); + clut = (carid - 1) * 6 * 32 + pgt3->texture_id * 6; + + civ_clut[carid][pgt3->texture_id][0] = texture_cluts[pgt3->texture_set][pgt3->texture_id]; cp->vindices = M_INT_4R(pgt3->v0, pgt3->v1, pgt3->v2, 0); cp->nindices = M_INT_4R(pgt3->n0, pgt3->n1, pgt3->n2, 0); - cp->clut_uv0 = M_INT_2((clut * 384 + pgt3->texture_id * 12 - 384) >> 1, * (ushort*)&pgt3->uv0); + cp->clut_uv0 = M_INT_2(clut, *(ushort*)&pgt3->uv0); cp->tpage_uv1 = M_INT_2(texture_pages[pgt3->texture_set], *(ushort *)&pgt3->uv1); cp->uv3_uv2 = *(ushort *)&pgt3->uv2; cp->originalindex = i; @@ -1098,12 +1101,14 @@ void buildNewCarFromModel(CAR_MODEL *car, MODEL *model, int first) { POLYGT4* pgt4 = (POLYGT4*)polyList; - clut = GetCarPalIndex(pgt4->texture_set); - civ_clut[clut][pgt4->texture_id][0] = texture_cluts[pgt4->texture_set][pgt4->texture_id]; + carid = GetCarPalIndex(pgt4->texture_set); + clut = (carid - 1) * 6 * 32 + pgt4->texture_id * 6; + + civ_clut[carid][pgt4->texture_id][0] = texture_cluts[pgt4->texture_set][pgt4->texture_id]; cp->vindices = M_INT_4R(pgt4->v0, pgt4->v1, pgt4->v2, 0); cp->nindices = M_INT_4R(pgt4->n0, pgt4->n1, pgt4->n2, 0); - cp->clut_uv0 = M_INT_2((clut * 384 + pgt4->texture_id * 12 - 384) >> 1, *(ushort*)&pgt4->uv0); + cp->clut_uv0 = M_INT_2(clut, *(ushort*)&pgt4->uv0); cp->tpage_uv1 = M_INT_2(texture_pages[pgt4->texture_set], *(ushort*)&pgt4->uv1); cp->uv3_uv2 = *(ushort*)&pgt4->uv2; cp->originalindex = i; @@ -1112,7 +1117,7 @@ void buildNewCarFromModel(CAR_MODEL *car, MODEL *model, int first) cp->vindices = M_INT_4R(pgt4->v0, pgt4->v2, pgt4->v3, 0); cp->nindices = M_INT_4R(pgt4->n0, pgt4->n2, pgt4->n3, 0); - cp->clut_uv0 = M_INT_2((clut * 384 + pgt4->texture_id * 12 - 384) >> 1, *(ushort*)&pgt4->uv0); + cp->clut_uv0 = M_INT_2(clut, *(ushort*)&pgt4->uv0); cp->tpage_uv1 = M_INT_2(texture_pages[pgt4->texture_set], *(ushort *)&pgt4->uv2); cp->uv3_uv2 = *(ushort *)&pgt4->uv3; cp->originalindex = i; diff --git a/src_rebuild/Game/C/denting.c b/src_rebuild/Game/C/denting.c index 308b124c..e45229a8 100644 --- a/src_rebuild/Game/C/denting.c +++ b/src_rebuild/Game/C/denting.c @@ -28,7 +28,7 @@ char* DentingFiles[] = u_char gCarDamageZoneVerts[MAX_CAR_MODELS][NUM_DAMAGE_ZONES][MAX_DAMAGE_ZONE_VERTS]; u_char gHDCarDamageZonePolys[MAX_CAR_MODELS][NUM_DAMAGE_ZONES][MAX_DAMAGE_ZONE_POLYS]; -u_char gHDCarDamageLevels[MAX_CAR_MODELS][MAX_DAMAGE_LEVELS]; +u_char gHDCarDamageLevels[MAX_CAR_MODELS][MAX_DAMAGE_LEVELS]; // the damage level (texture) count for polygons // [D] [T] void InitialiseDenting(void) @@ -66,12 +66,11 @@ void DentCar(CAR_DATA *cp) // collect vertices from zones if (pCleanModel != NULL) { - VertNo = 0; - while (VertNo < pCleanModel->num_vertices) - tempDamage[VertNo++] = 0; + for (VertNo = 0; VertNo < pCleanModel->num_vertices; VertNo++) + tempDamage[VertNo] = 0; - Zone = 0; - do { + for (Zone = 0; Zone < NUM_DAMAGE_ZONES; Zone++) + { Damage = cp->ap.damage[Zone]; if (Damage > MaxDamage) @@ -79,21 +78,14 @@ void DentCar(CAR_DATA *cp) DamPtr = gCarDamageZoneVerts[cp->ap.model][Zone]; - VertNo = 0; - while (VertNo < MAX_DAMAGE_ZONE_VERTS && *DamPtr != 0xFF) + for (VertNo = 0; VertNo < MAX_DAMAGE_ZONE_VERTS && *DamPtr != 0xFF; VertNo++, DamPtr++) { if (tempDamage[*DamPtr] == 0) tempDamage[*DamPtr] += Damage; else tempDamage[*DamPtr] += Damage / 2; - - DamPtr++; - - VertNo++; } - - Zone++; - } while (Zone < NUM_DAMAGE_ZONES); + } } // update vertices positon @@ -102,17 +94,11 @@ void DentCar(CAR_DATA *cp) DamVertPtr = (SVECTOR *)gCarDamModelPtr[model]->vertices; CleanVertPtr = (SVECTOR *)gCarCleanModelPtr[model]->vertices; - VertNo = 0; - while (VertNo < pCleanModel->num_vertices) + for (VertNo = 0; VertNo < pCleanModel->num_vertices; VertNo++, DamVertPtr++, CleanVertPtr++) { gTempCarVertDump[cp->id][VertNo].vx = CleanVertPtr->vx + FIXEDH((DamVertPtr->vx - CleanVertPtr->vx) * tempDamage[VertNo] / 2); gTempCarVertDump[cp->id][VertNo].vy = CleanVertPtr->vy + FIXEDH((DamVertPtr->vy - CleanVertPtr->vy) * tempDamage[VertNo] / 2); gTempCarVertDump[cp->id][VertNo].vz = CleanVertPtr->vz + FIXEDH((DamVertPtr->vz - CleanVertPtr->vz) * tempDamage[VertNo] / 2); - - DamVertPtr++; - CleanVertPtr++; - - VertNo++; } } @@ -122,21 +108,22 @@ void DentCar(CAR_DATA *cp) dentptr = gTempHDCarUVDump[cp->id]; // reset UV coordinates - Poly = 0; - while (Poly < pCleanModel->num_polys) + + for (Poly = 0; Poly < pCleanModel->num_polys; Poly++) { dentptr->u3 = 0; - Poly++; dentptr++; } - Zone = 0; - do { + for(Zone = 0; Zone < NUM_DAMAGE_ZONES; Zone++) + { Damage = cp->ap.damage[Zone]; - Poly = 0; - while (Poly < MAX_DAMAGE_ZONE_POLYS && gHDCarDamageZonePolys[cp->ap.model][Zone][Poly] != 0xFF) + for (Poly = 0; Poly < MAX_DAMAGE_ZONE_POLYS; Poly++) { + if (gHDCarDamageZonePolys[cp->ap.model][Zone][Poly] == 0xFF) + break; + dentptr = gTempHDCarUVDump[cp->id] + gHDCarDamageZonePolys[cp->ap.model][Zone][Poly]; // add a damage level @@ -145,28 +132,17 @@ void DentCar(CAR_DATA *cp) // clamp level if (dentptr->u3 > 2) dentptr->u3 = 2; - - Poly++; } - - Zone++; - } while (Zone < NUM_DAMAGE_ZONES); - - Poly = 0; + } DamPtr = gHDCarDamageLevels[model]; dentptr = gTempHDCarUVDump[cp->id]; - while (Poly < pCleanModel->num_polys) + for (Poly = 0; Poly < pCleanModel->num_polys; Poly++, DamPtr++, dentptr++) { // calculate the UV offset with strange XORs if(dentptr->u3 > 0) dentptr->u3 = (*DamPtr ^ 1 ^ (*DamPtr ^ 1 | dentptr->u3)) * 64; - - dentptr++; - - DamPtr++; - Poly++; } } } @@ -194,11 +170,9 @@ void CreateDentableCar(CAR_DATA *cp) while (vcount-- != -1) *dst++ = *src++; - count = 0; - while (count < srcModel->num_polys) + for (count = 0; count < srcModel->num_polys; count++) { gTempHDCarUVDump[cp->id][count].u3 = 0; - count++; } } else @@ -209,11 +183,9 @@ void CreateDentableCar(CAR_DATA *cp) srcModel = gCarLowModelPtr[model]; if (srcModel != NULL) { - count = 0; - while (count < srcModel->num_polys) + for (count = 0; count < srcModel->num_polys; count++) { gTempLDCarUVDump[cp->id][count].u3 = 0; - count++; } } else @@ -223,11 +195,9 @@ void CreateDentableCar(CAR_DATA *cp) if (gDontResetCarDamage == 0) { - count = 0; - while (count < NUM_DAMAGE_ZONES) + for (count = 0; count < NUM_DAMAGE_ZONES; count++) { cp->ap.damage[count] = 0; - count++; } cp->totalDamage = 0; @@ -436,9 +406,7 @@ void ProcessDentLump(char *lump_ptr, int lump_size) int offset; u_char* mem; - i = 0; - - while (i < MAX_CAR_MODELS) + for (i = 0; i < MAX_CAR_MODELS; i++) { model = MissionHeader->residentModels[i]; @@ -477,8 +445,6 @@ void ProcessDentLump(char *lump_ptr, int lump_size) memcpy((u_char*)gHDCarDamageLevels[i], mem + offset, MAX_FILE_DAMAGE_LEVELS); } - - i++; } } From 66d45563d11c22482c6676dd99650941a2db1124 Mon Sep 17 00:00:00 2001 From: SoapyMan Date: Sun, 9 Apr 2023 21:11:28 +0600 Subject: [PATCH 15/20] - bail out safely when CompleteSoundSetup fails if sound is not present --- src_rebuild/Game/C/sound.c | 56 ++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/src_rebuild/Game/C/sound.c b/src_rebuild/Game/C/sound.c index de7faa64..288e4a9c 100644 --- a/src_rebuild/Game/C/sound.c +++ b/src_rebuild/Game/C/sound.c @@ -475,41 +475,39 @@ int CompleteSoundSetup(int channel, int bank, int sample, int pitch, int proximi if (bpf == 0) { - channel = -1; + return -1; } - else - { - chan = &channels[channel]; + + chan = &channels[channel]; - if (gSoundMode == 1 && proximity != -1) - UpdateVolumeAttributesS(channel, proximity); - else - UpdateVolumeAttributesM(channel); + if (gSoundMode == 1 && proximity != -1) + UpdateVolumeAttributesS(channel, proximity); + else + UpdateVolumeAttributesM(channel); - stop_sound_handler = 1; + stop_sound_handler = 1; - chan->attr.mask = SPU_VOICE_VOLL | SPU_VOICE_VOLR | SPU_VOICE_VOLMODEL | SPU_VOICE_VOLMODER | SPU_VOICE_PITCH | SPU_VOICE_WDSA; - chan->attr.addr = samp->address; - chan->attr.pitch = MIN(rate / 44100, 16383); - chan->time = (samp->length / bpf) * 2 + 2; + chan->attr.mask = SPU_VOICE_VOLL | SPU_VOICE_VOLR | SPU_VOICE_VOLMODEL | SPU_VOICE_VOLMODER | SPU_VOICE_PITCH | SPU_VOICE_WDSA; + chan->attr.addr = samp->address; + chan->attr.pitch = MIN(rate / 44100, 16383); + chan->time = (samp->length / bpf) * 2 + 2; - chan->flags &= ~CHAN_LOOP; - chan->flags |= samp->loop ? CHAN_LOOP : 0; + chan->flags &= ~CHAN_LOOP; + chan->flags |= samp->loop ? CHAN_LOOP : 0; - chan->samplerate = samp->samplerate; + chan->samplerate = samp->samplerate; - if (sound_paused != 0) - { - chan->attr.volume.left = 0; - chan->attr.volume.right = 0; - } - - SpuSetVoiceAttr(&chan->attr); - SpuSetKey(1, chan->attr.voice); - - stop_sound_handler = 0; + if (sound_paused != 0) + { + chan->attr.volume.left = 0; + chan->attr.volume.right = 0; } + SpuSetVoiceAttr(&chan->attr); + SpuSetKey(1, chan->attr.voice); + + stop_sound_handler = 0; + return channel; } @@ -593,6 +591,9 @@ int Start3DTrackingSound(int channel, int bank, int sample, VECTOR *position, LO channel = CompleteSoundSetup(channel, bank, sample, 4096, 0); + if (channel < 0) + return -1; + ComputeDoppler(&channels[channel]); SetChannelPitch(channel, 4096); @@ -621,6 +622,9 @@ int Start3DSoundVolPitch(int channel, int bank, int sample, int x, int y, int z, channel = CompleteSoundSetup(channel, bank, sample, pitch, 0); + if (channel < 0) + return -1; + ComputeDoppler(&channels[channel]); SetChannelPitch(channel, pitch); From 0bbd2a384fa9dd30c4d8675360e31c99a97d2ac1 Mon Sep 17 00:00:00 2001 From: SoapyMan Date: Sun, 9 Apr 2023 21:11:52 +0600 Subject: [PATCH 16/20] - delete unused stuff --- src_rebuild/Game/C/pause.c | 1 - src_rebuild/Game/engine/mdl.h | 20 -------------------- 2 files changed, 21 deletions(-) diff --git a/src_rebuild/Game/C/pause.c b/src_rebuild/Game/C/pause.c index e271b77b..45f10692 100644 --- a/src_rebuild/Game/C/pause.c +++ b/src_rebuild/Game/C/pause.c @@ -259,7 +259,6 @@ MENU_HEADER DebugJustForFunHeader = MENU_ITEM DebugOptionsItems[] = { #ifdef CUTSCENE_RECORDER - //{ gCutsceneRecorderPauseText, 5u, 2u, (pauseFunc)&NextCutsceneRecorderPlayer, MENU_QUIT_NONE, NULL }, { gCurrentChasePauseText, 5u, 2u, (pauseFunc)&CutRec_NextChase, MENU_QUIT_NONE, NULL }, #endif { "Display position", PAUSE_TYPE_FUNC, 2, SetDisplayPosition, MENU_QUIT_NONE, NULL}, diff --git a/src_rebuild/Game/engine/mdl.h b/src_rebuild/Game/engine/mdl.h index 9ee02a21..8d552de8 100644 --- a/src_rebuild/Game/engine/mdl.h +++ b/src_rebuild/Game/engine/mdl.h @@ -160,26 +160,6 @@ struct MODEL int normals; int point_normals; int collision_block; - - SVECTOR* pVertex(int i) const - { - return (SVECTOR *)(((u_char *)this) + vertices) + i; - } - - SVECTOR* pNormal(int i) const - { - return (SVECTOR *)(((u_char *)this) + point_normals) + i; - } - - COLLISION_PACKET* pCollisionPacket(int i) const - { - return (COLLISION_PACKET *)(((u_char *)this) + collision_block) + i; - } - - char* pPolyAt(int ofs) const - { - return (char *)(((u_char *)this) + poly_block + ofs); - } }; From 078694290d434e8a520bc1971a4b37ccd7f54e85 Mon Sep 17 00:00:00 2001 From: SoapyMan Date: Sun, 9 Apr 2023 21:12:09 +0600 Subject: [PATCH 17/20] - fix mistake in hypot --- src_rebuild/Game/C/leadai.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src_rebuild/Game/C/leadai.c b/src_rebuild/Game/C/leadai.c index 2d3b55ea..dc2d06d9 100644 --- a/src_rebuild/Game/C/leadai.c +++ b/src_rebuild/Game/C/leadai.c @@ -2816,8 +2816,9 @@ u_int hypot(int x, int y) if (x < y) { + t = y; y = x; - x = y; + x = t; } if (x < 0x8000) From 3e136cce781735e9daffb74269fb5d804157cd76 Mon Sep 17 00:00:00 2001 From: SoapyMan Date: Mon, 17 Apr 2023 20:08:56 +0600 Subject: [PATCH 18/20] - slight rework for ProcessPalletLump --- src_rebuild/Game/C/cars.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src_rebuild/Game/C/cars.c b/src_rebuild/Game/C/cars.c index 22f5dc82..24363dd6 100644 --- a/src_rebuild/Game/C/cars.c +++ b/src_rebuild/Game/C/cars.c @@ -1242,7 +1242,7 @@ void MangleWheelModels(void) src++; } - } while (++i < 3); + } // HACK: Show clean model only in Rio. //if (GameLevel == 3) @@ -1276,24 +1276,23 @@ void ProcessPalletLump(char *lump_ptr, int lump_size) texnum = buffPtr[1]; tpageindex = buffPtr[2]; clut_number = buffPtr[3]; + buffPtr += 4; if (clut_number == -1) { // store clut - LoadImage(&clutpos, (u_long*)(buffPtr + 4)); + LoadImage(&clutpos, (u_long*)buffPtr); + buffPtr += 8; clutValue = GetClut(clutpos.x, clutpos.y); - *clutTablePtr++ = clutValue; - IncrementClutNum(&clutpos); - buffPtr += 12; + *clutTablePtr++ = clutValue; } else { // use stored clut clutValue = clutTable[clut_number]; - buffPtr += 4; } civ_clut[GetCarPalIndex(tpageindex)][texnum][palette + 1] = clutValue; From fb09d8c171838b4bb1bf6e6ce3190442842a80cb Mon Sep 17 00:00:00 2001 From: SoapyMan Date: Mon, 17 Apr 2023 20:09:12 +0600 Subject: [PATCH 19/20] index on develop-SoapyMan: 3e136cce - slight rework for ProcessPalletLump From dc441146a1d5547750fae7582ed696f015bf9a22 Mon Sep 17 00:00:00 2001 From: SoapyMan Date: Fri, 21 Apr 2023 16:37:21 +0600 Subject: [PATCH 20/20] - remove area data loading hack and change condition to fix the original way of handling it --- src_rebuild/Game/C/spool.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src_rebuild/Game/C/spool.c b/src_rebuild/Game/C/spool.c index 7ee7e925..a527bbfc 100644 --- a/src_rebuild/Game/C/spool.c +++ b/src_rebuild/Game/C/spool.c @@ -715,6 +715,7 @@ void CheckValidSpoolData(void) if (models_ready) init_spooled_models(); +#ifdef PSX if (spoolactive && check_regions_present()) { stopgame(); @@ -727,6 +728,7 @@ void CheckValidSpoolData(void) startgame(); } +#endif // PSX } // [D] [T] @@ -759,14 +761,6 @@ void CheckLoadAreaData(int cellx, int cellz) spoolptr = (Spool *)(RegionSpoolInfo + spoolinfo_offsets[current_region]); -#ifndef PSX - // [A] this fixes spooling not activated bug (reversing bug?) - if (LoadedArea != spoolptr->super_region && spoolptr->super_region != 0xFF && old_region != -1) - { - LoadedArea = spoolptr->super_region; - } - else -#endif if (old_region == -1 && spoolptr->super_region != 0xFF) { // just load the area if no @@ -778,7 +772,7 @@ void CheckLoadAreaData(int cellx, int cellz) if (old_region == -1) LoadedArea = -1; - else if (/*spoolptr->super_region == 0xFF ||*/ nAreas == 0) + else if (spoolptr->super_region == 0xFF && nAreas == 0) return; #define BOUNDARY_MIN 15