Full Code of SFTtech/openage for AI

master 865bd548d5bc cached
1669 files
7.2 MB
2.0M tokens
3891 symbols
1 requests
Download .txt
Showing preview only (7,850K chars total). Download the full file or copy to clipboard to get everything.
Repository: SFTtech/openage
Branch: master
Commit: 865bd548d5bc
Files: 1669
Total size: 7.2 MB

Directory structure:
gitextract_3ogk531m/

├── .clang-format
├── .github/
│   ├── PULL_REQUEST_TEMPLATES/
│   │   ├── pull_request_template.md
│   │   └── release_template.md
│   └── workflows/
│       ├── macosx-ci.yml
│       ├── ubuntu-24.04.yml
│       ├── windows-server-2019.yml
│       └── windows-server-2022.yml
├── .gitignore
├── .mailmap
├── CMakeLists.txt
├── Makefile
├── README.md
├── assets/
│   ├── .gitignore
│   ├── CMakeLists.txt
│   ├── logo/
│   │   └── CMakeLists.txt
│   ├── qml/
│   │   ├── .gitignore
│   │   ├── Actions.qml
│   │   ├── ActionsGrid.qml
│   │   ├── BindsHelp.qml
│   │   ├── ButtonExtruded.qml
│   │   ├── ButtonExtrudedStyle.qml
│   │   ├── ButtonFlat.qml
│   │   ├── ButtonFlatStyle.qml
│   │   ├── CheckBoxFlat.qml
│   │   ├── CheckBoxFlatStyle.qml
│   │   ├── CreateGameWhenReady.qml
│   │   ├── GeneratorControl.qml
│   │   ├── GeneratorParametersConfiguration.qml
│   │   ├── IngameHud.qml
│   │   ├── Paper.qml
│   │   ├── TextFieldFlat.qml
│   │   ├── TextFieldFlatStyle.qml
│   │   ├── TypePicker.qml
│   │   └── main.qml
│   ├── shaders/
│   │   ├── CMakeLists.txt
│   │   ├── alphamask.frag.glsl
│   │   ├── alphamask.vert.glsl
│   │   ├── equalsEpsilon.glsl
│   │   ├── final.frag.glsl
│   │   ├── final.vert.glsl
│   │   ├── hud_drag_select.frag.glsl
│   │   ├── hud_drag_select.vert.glsl
│   │   ├── identity.vert.glsl
│   │   ├── maptexture.frag.glsl
│   │   ├── maptexture.vert.glsl
│   │   ├── skybox.frag.glsl
│   │   ├── skybox.vert.glsl
│   │   ├── teamcolors.frag.glsl
│   │   ├── terrain.frag.glsl
│   │   ├── terrain.vert.glsl
│   │   ├── texturefont.frag.glsl
│   │   ├── texturefont.vert.glsl
│   │   ├── world2d.frag.glsl
│   │   ├── world2d.vert.glsl
│   │   └── world3d.vert.glsl
│   ├── test/
│   │   ├── CMakeLists.txt
│   │   ├── nyan/
│   │   │   ├── CMakeLists.txt
│   │   │   └── pong.nyan
│   │   ├── qml/
│   │   │   ├── CMakeLists.txt
│   │   │   └── main.qml
│   │   ├── shaders/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── demo_0_display.frag.glsl
│   │   │   ├── demo_0_display.vert.glsl
│   │   │   ├── demo_1_display.frag.glsl
│   │   │   ├── demo_1_display.vert.glsl
│   │   │   ├── demo_1_obj.frag.glsl
│   │   │   ├── demo_1_obj.vert.glsl
│   │   │   ├── demo_2_display.frag.glsl
│   │   │   ├── demo_2_display.vert.glsl
│   │   │   ├── demo_2_obj.frag.glsl
│   │   │   ├── demo_2_obj.vert.glsl
│   │   │   ├── demo_4_display.frag.glsl
│   │   │   ├── demo_4_display.vert.glsl
│   │   │   ├── demo_4_obj.frag.glsl
│   │   │   ├── demo_4_obj.vert.glsl
│   │   │   ├── demo_5_obj.frag.glsl
│   │   │   ├── demo_5_obj.vert.glsl
│   │   │   ├── demo_6_2d.frag.glsl
│   │   │   ├── demo_6_2d.vert.glsl
│   │   │   ├── demo_6_2d_frame.frag.glsl
│   │   │   ├── demo_6_2d_frame.vert.glsl
│   │   │   ├── demo_6_2d_frustum_frame.vert.glsl
│   │   │   ├── demo_6_3d.frag.glsl
│   │   │   ├── demo_6_3d.vert.glsl
│   │   │   ├── demo_6_display.frag.glsl
│   │   │   ├── demo_6_display.vert.glsl
│   │   │   ├── demo_7_shader_command.frag.glsl
│   │   │   ├── demo_7_shader_command.vert.glsl
│   │   │   ├── demo_7_snippets/
│   │   │   │   ├── alpha.snippet
│   │   │   │   └── color.snippet
│   │   │   └── pathfinding/
│   │   │       ├── CMakeLists.txt
│   │   │       ├── demo_0_cost_field.frag.glsl
│   │   │       ├── demo_0_cost_field.vert.glsl
│   │   │       ├── demo_0_display.frag.glsl
│   │   │       ├── demo_0_display.vert.glsl
│   │   │       ├── demo_0_flow_field.frag.glsl
│   │   │       ├── demo_0_flow_field.vert.glsl
│   │   │       ├── demo_0_grid.frag.glsl
│   │   │       ├── demo_0_grid.vert.glsl
│   │   │       ├── demo_0_integration_field.frag.glsl
│   │   │       ├── demo_0_integration_field.vert.glsl
│   │   │       ├── demo_0_obj.frag.glsl
│   │   │       ├── demo_0_obj.vert.glsl
│   │   │       ├── demo_0_vector.frag.glsl
│   │   │       ├── demo_0_vector.vert.glsl
│   │   │       ├── demo_1_display.frag.glsl
│   │   │       ├── demo_1_display.vert.glsl
│   │   │       ├── demo_1_grid.frag.glsl
│   │   │       ├── demo_1_grid.vert.glsl
│   │   │       ├── demo_1_obj.frag.glsl
│   │   │       └── demo_1_obj.vert.glsl
│   │   └── textures/
│   │       ├── CMakeLists.txt
│   │       ├── test_animation.sprite
│   │       ├── test_gaben.sprite
│   │       ├── test_gaben.texture
│   │       ├── test_missing.sprite
│   │       ├── test_missing.texture
│   │       ├── test_tank.sprite
│   │       ├── test_tank.texture
│   │       ├── test_tank_mirrored.sprite
│   │       ├── test_terrain.terrain
│   │       ├── test_terrain.texture
│   │       ├── test_terrain2.terrain
│   │       ├── test_terrain2.texture
│   │       └── test_texture.texture
│   └── textures/
│       ├── CMakeLists.txt
│       └── torn_paper_edge.docx
├── buildsystem/
│   ├── CheckCompilerFeatures.cmake
│   ├── CheckInSourceBuild.cmake
│   ├── CheckRuntimeDependencies.cmake
│   ├── DependencyFetch.cmake
│   ├── DetectProjectVersion.cmake
│   ├── HandleCXXOptions.cmake
│   ├── HandlePythonOptions.cmake
│   ├── __init__.py
│   ├── check_py_file_list.py
│   ├── codecompliance/
│   │   ├── __init__.py
│   │   ├── __main__.py
│   │   ├── authors.py
│   │   ├── clangtidy.py
│   │   ├── cppstyle.py
│   │   ├── cython.py
│   │   ├── headerguards.py
│   │   ├── legal.py
│   │   ├── modes.py
│   │   ├── pylint.py
│   │   ├── pystyle.py
│   │   ├── textfiles.py
│   │   └── util.py
│   ├── codegen.cmake
│   ├── compilepy.py
│   ├── cpp.cmake
│   ├── cythonize.py
│   ├── doxygen.cmake
│   ├── doxygen_custom.css
│   ├── inplacemodules.py
│   ├── modules/
│   │   ├── DownloadCache.cmake
│   │   ├── FindCython.cmake
│   │   ├── FindEpoxy.cmake
│   │   ├── FindGCCBacktrace.cmake
│   │   ├── FindGPerfTools.cmake
│   │   ├── FindHarfBuzz.cmake
│   │   ├── FindInotify.cmake
│   │   ├── FindOgg.cmake
│   │   ├── FindOpusfile.cmake
│   │   ├── FindPython.cmake
│   │   └── FindPython_test.cpp
│   ├── options.cmake
│   ├── pxdgen.py
│   ├── python.cmake
│   ├── scripts/
│   │   ├── EmbedFont.cmake
│   │   ├── EmbedPython.cmake
│   │   ├── EmbedWinDependencies.cmake
│   │   └── copy_modules.py
│   ├── templates/
│   │   ├── Doxyfile.in
│   │   ├── ExternalFetch.cmake.in
│   │   ├── ForwardVariables.cmake.in
│   │   ├── openage.bat.in
│   │   └── qt.conf
│   └── util.cmake
├── cfg/
│   ├── .gitignore
│   ├── CMakeLists.txt
│   ├── converter/
│   │   └── games/
│   │       ├── aoc/
│   │       │   └── version_hashes.toml
│   │       ├── aoc_demo/
│   │       │   └── version_hashes.toml
│   │       ├── aok/
│   │       │   └── version_hashes.toml
│   │       ├── de1/
│   │       │   └── version_hashes.toml
│   │       ├── de2/
│   │       │   └── version_hashes.toml
│   │       ├── game_editions.toml
│   │       ├── game_expansions.toml
│   │       ├── hd/
│   │       │   └── version_hashes.toml
│   │       ├── hd_ak/
│   │       │   └── version_hashes.toml
│   │       ├── hd_fgt/
│   │       │   └── version_hashes.toml
│   │       ├── hd_raj/
│   │       │   └── version_hashes.toml
│   │       ├── ror/
│   │       │   └── version_hashes.toml
│   │       ├── swgb/
│   │       │   └── version_hashes.toml
│   │       └── swgb_cc/
│   │           └── version_hashes.toml
│   └── keybinds.oac
├── changelog.md
├── configure
├── copying.md
├── dist/
│   ├── CMakeLists.txt
│   ├── README.md
│   └── openage.desktop
├── doc/
│   ├── README.md
│   ├── assets.md
│   ├── build_instructions/
│   │   ├── arch_linux.md
│   │   ├── debian.md
│   │   ├── docker.md
│   │   ├── fedora.md
│   │   ├── freebsd.md
│   │   ├── gentoo.md
│   │   ├── macos.md
│   │   ├── nix.md
│   │   ├── opensuse.md
│   │   ├── ubuntu.md
│   │   └── windows_msvc.md
│   ├── building.md
│   ├── buildsystem.md
│   ├── changelogs/
│   │   ├── engine/
│   │   │   ├── v0.0.0.md
│   │   │   ├── v0.1.0.md
│   │   │   ├── v0.2.0.md
│   │   │   ├── v0.2.1.md
│   │   │   ├── v0.2.2.md
│   │   │   ├── v0.2.3.md
│   │   │   ├── v0.3.0-alpha.md
│   │   │   ├── v0.3.0.md
│   │   │   ├── v0.4.0.md
│   │   │   ├── v0.4.1.md
│   │   │   ├── v0.5.0.md
│   │   │   ├── v0.5.1.md
│   │   │   ├── v0.5.2.md
│   │   │   ├── v0.5.3.md
│   │   │   └── v0.6.0.md
│   │   └── nyan_api/
│   │       ├── v0.1.0.md
│   │       ├── v0.2.0.md
│   │       ├── v0.3.0.md
│   │       ├── v0.4.0.md
│   │       ├── v0.4.1.md
│   │       ├── v0.5.0.md
│   │       └── v0.6.0.md
│   ├── code/
│   │   ├── README.md
│   │   ├── architecture.md
│   │   ├── converter/
│   │   │   ├── README.md
│   │   │   ├── architecture_overview.md
│   │   │   └── workflow.md
│   │   ├── coordinate-systems.md
│   │   ├── curves.md
│   │   ├── event_system.md
│   │   ├── exceptions.md
│   │   ├── game_simulation/
│   │   │   ├── README.md
│   │   │   ├── activity.md
│   │   │   ├── components.md
│   │   │   ├── game_entity.md
│   │   │   └── systems.md
│   │   ├── gui.md
│   │   ├── images/
│   │   │   ├── component_classes.uxf
│   │   │   ├── continuous_curve.ggb
│   │   │   ├── curves_classes.uxf
│   │   │   ├── discrete_curve.ggb
│   │   │   ├── engine_architecture.uxf
│   │   │   ├── event_classes.uxf
│   │   │   ├── game_entity_classes.uxf
│   │   │   ├── pathfinder_architecture.uxf
│   │   │   ├── segmented_curve.ggb
│   │   │   ├── simulation.uxf
│   │   │   ├── system_classes.uxf
│   │   │   └── time_classes.uxf
│   │   ├── input/
│   │   │   └── README.md
│   │   ├── logger.md
│   │   ├── optimization.md
│   │   ├── pathfinding/
│   │   │   ├── README.md
│   │   │   └── field_types.md
│   │   ├── pyinterface.md
│   │   ├── renderer/
│   │   │   ├── README.md
│   │   │   ├── demos.md
│   │   │   ├── level1.md
│   │   │   └── level2.md
│   │   ├── testing.md
│   │   └── time.md
│   ├── contributing.md
│   ├── convert/
│   │   ├── README.md
│   │   ├── convert_single_file.md
│   │   ├── debugger.md
│   │   ├── interactive.md
│   │   └── nyan.md
│   ├── debug.md
│   ├── development.md
│   ├── ide/
│   │   ├── README.md
│   │   ├── configs/
│   │   │   └── vscode/
│   │   │       └── tasks.json
│   │   ├── emacs.md
│   │   ├── qt_creator.md
│   │   └── vscode.md
│   ├── ideas/
│   │   ├── ai.md
│   │   ├── editor/
│   │   │   ├── README.md
│   │   │   ├── campaigns.md
│   │   │   ├── economy.md
│   │   │   ├── multiplayer.md
│   │   │   ├── scripting.md
│   │   │   ├── tech.md
│   │   │   ├── terrain-ui.txt
│   │   │   ├── terrain.md
│   │   │   └── units.md
│   │   ├── fr_technical_overview.md
│   │   ├── gameplay.md
│   │   ├── interface.md
│   │   └── technical.md
│   ├── media/
│   │   ├── aoc-slp-list.md
│   │   ├── blendomatic.md
│   │   ├── drs-files.md
│   │   ├── evolution-openage-gource.md
│   │   ├── filtermaps-dat.md
│   │   ├── lzx_compression_info.md
│   │   ├── openage/
│   │   │   ├── blendmask_format_spec.md
│   │   │   ├── blendtable_format_spec.md
│   │   │   ├── file_referencing.md
│   │   │   ├── modpack_definition_file.md
│   │   │   ├── modpacks.md
│   │   │   ├── palette_format_spec.md
│   │   │   ├── sprite_format_spec.md
│   │   │   ├── terrain_format_spec.md
│   │   │   └── texture_format_spec.md
│   │   ├── original-metadata.md
│   │   ├── patterns/
│   │   │   ├── sld.hexpat
│   │   │   ├── slp.hexpat
│   │   │   └── slp_v4.hexpat
│   │   ├── sld-files.md
│   │   ├── slp-files.md
│   │   ├── smp-files.md
│   │   ├── smx-files.md
│   │   ├── sound.md
│   │   ├── stemplet-dat.md
│   │   └── terrain.md
│   ├── media_convert.md
│   ├── nyan/
│   │   ├── README.md
│   │   ├── aoe2_nyan_tree.uxf
│   │   ├── api_reference/
│   │   │   ├── reference_ability.md
│   │   │   ├── reference_effect.md
│   │   │   ├── reference_modifier.md
│   │   │   ├── reference_resistance.md
│   │   │   ├── reference_root.md
│   │   │   └── reference_util.md
│   │   └── openage-lib.md
│   ├── project_structure.md
│   ├── releasing.md
│   ├── reverse_engineering/
│   │   ├── aoc_structures_00_09_26_0809
│   │   ├── civilizations.md
│   │   ├── game_mechanics/
│   │   │   ├── accuracy.md
│   │   │   ├── attacking_alarm.md
│   │   │   ├── build_speed.md
│   │   │   ├── building_placement.md
│   │   │   ├── damage.md
│   │   │   ├── formations.md
│   │   │   ├── garrison.md
│   │   │   ├── market.md
│   │   │   ├── monk_conversion.md
│   │   │   ├── pathfinding.md
│   │   │   ├── ram_speed.md
│   │   │   ├── rates.md
│   │   │   ├── repair.md
│   │   │   ├── research.md
│   │   │   ├── selection.md
│   │   │   ├── swgb/
│   │   │   │   ├── power.md
│   │   │   │   ├── shields.md
│   │   │   │   ├── stealth.md
│   │   │   │   └── user-interface.md
│   │   │   ├── switching_villager_tasks.md
│   │   │   ├── town_bell.md
│   │   │   ├── waypoints.md
│   │   │   └── wolves.md
│   │   ├── networking/
│   │   │   ├── 01-general.md
│   │   │   ├── 02-header.md
│   │   │   ├── 03-sync.md
│   │   │   ├── 04-lobby.md
│   │   │   ├── 05-chat_protocol.md
│   │   │   ├── 06-chat_message_spoofing.md
│   │   │   ├── 07-primary_action.md
│   │   │   ├── 08-movement.md
│   │   │   ├── 09-formation.md
│   │   │   ├── 10-unit_creation.md
│   │   │   ├── 11-buildings.md
│   │   │   ├── 12-market.md
│   │   │   ├── 13-other.md
│   │   │   ├── 14-ai.md
│   │   │   ├── 15-c-structs.md
│   │   │   └── technology_ids.md
│   │   ├── scoring.md
│   │   └── unit_stats/
│   │       ├── unit_stats.md
│   │       ├── unit_stats_afr.csv
│   │       ├── unit_stats_aoc.csv
│   │       ├── unit_stats_aoe.csv
│   │       ├── unit_stats_aoe.txt
│   │       ├── unit_stats_aok.csv
│   │       └── unit_stats_fe.csv
│   ├── running.md
│   └── troubleshooting.md
├── etc/
│   ├── gdb_pretty/
│   │   ├── __init__.py
│   │   └── printers.py
│   ├── lsan.supp
│   ├── openage.gdbinit
│   ├── pylintrc
│   └── valgrind-python.supp
├── flake.nix
├── kevinfile
├── legal/
│   ├── BSD-3-clause
│   ├── GPLv3
│   └── LGPLv2.0
├── libopenage/
│   ├── .gitignore
│   ├── CMakeLists.txt
│   ├── assets/
│   │   ├── CMakeLists.txt
│   │   ├── mod_manager.cpp
│   │   ├── mod_manager.h
│   │   ├── modpack.cpp
│   │   └── modpack.h
│   ├── audio/
│   │   ├── CMakeLists.txt
│   │   ├── audio_manager.cpp
│   │   ├── audio_manager.h
│   │   ├── category.cpp
│   │   ├── category.h
│   │   ├── dynamic_loader.cpp
│   │   ├── dynamic_loader.h
│   │   ├── dynamic_resource.cpp
│   │   ├── dynamic_resource.h
│   │   ├── error.cpp
│   │   ├── error.h
│   │   ├── format.cpp
│   │   ├── format.h
│   │   ├── hash_functions.h
│   │   ├── in_memory_loader.cpp
│   │   ├── in_memory_loader.h
│   │   ├── in_memory_resource.cpp
│   │   ├── in_memory_resource.h
│   │   ├── loader_policy.cpp
│   │   ├── loader_policy.h
│   │   ├── opus_dynamic_loader.cpp
│   │   ├── opus_dynamic_loader.h
│   │   ├── opus_in_memory_loader.cpp
│   │   ├── opus_in_memory_loader.h
│   │   ├── opus_loading.cpp
│   │   ├── opus_loading.h
│   │   ├── resource.cpp
│   │   ├── resource.h
│   │   ├── resource_def.cpp
│   │   ├── resource_def.h
│   │   ├── sound.cpp
│   │   ├── sound.h
│   │   └── types.h
│   ├── config.cpp.in
│   ├── config.h.in
│   ├── console/
│   │   ├── CMakeLists.txt
│   │   ├── buf.cpp
│   │   ├── buf.h
│   │   ├── console.cpp
│   │   ├── console.h
│   │   ├── draw.cpp
│   │   ├── draw.h
│   │   └── tests.cpp
│   ├── coord/
│   │   ├── CMakeLists.txt
│   │   ├── chunk.cpp
│   │   ├── chunk.h
│   │   ├── coord.cpp.template
│   │   ├── coord.h.template
│   │   ├── coord_test.cpp
│   │   ├── declarations.cpp
│   │   ├── declarations.h
│   │   ├── phys.cpp
│   │   ├── phys.h
│   │   ├── pixel.cpp
│   │   ├── pixel.h
│   │   ├── scene.cpp
│   │   ├── scene.h
│   │   ├── term.cpp
│   │   ├── term.h
│   │   ├── tile.cpp
│   │   └── tile.h
│   ├── curve/
│   │   ├── CMakeLists.txt
│   │   ├── base_curve.cpp
│   │   ├── base_curve.h
│   │   ├── container/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── array.cpp
│   │   │   ├── array.h
│   │   │   ├── element_wrapper.cpp
│   │   │   ├── element_wrapper.h
│   │   │   ├── iterator.cpp
│   │   │   ├── iterator.h
│   │   │   ├── map.cpp
│   │   │   ├── map.h
│   │   │   ├── map_filter_iterator.cpp
│   │   │   ├── map_filter_iterator.h
│   │   │   ├── queue.cpp
│   │   │   ├── queue.h
│   │   │   ├── queue_filter_iterator.cpp
│   │   │   └── queue_filter_iterator.h
│   │   ├── continuous.cpp
│   │   ├── continuous.h
│   │   ├── discrete.cpp
│   │   ├── discrete.h
│   │   ├── discrete_mod.cpp
│   │   ├── discrete_mod.h
│   │   ├── interpolated.cpp
│   │   ├── interpolated.h
│   │   ├── keyframe.cpp
│   │   ├── keyframe.h
│   │   ├── keyframe_container.cpp
│   │   ├── keyframe_container.h
│   │   ├── segmented.cpp
│   │   ├── segmented.h
│   │   └── tests/
│   │       ├── CMakeLists.txt
│   │       ├── container.cpp
│   │       └── curve_types.cpp
│   ├── cvar/
│   │   ├── CMakeLists.txt
│   │   ├── cvar.cpp
│   │   └── cvar.h
│   ├── datastructure/
│   │   ├── CMakeLists.txt
│   │   ├── concurrent_queue.h
│   │   ├── constexpr_map.h
│   │   ├── pairing_heap.h
│   │   ├── tests.cpp
│   │   └── tests.h
│   ├── engine/
│   │   ├── CMakeLists.txt
│   │   ├── engine.cpp
│   │   └── engine.h
│   ├── error/
│   │   ├── CMakeLists.txt
│   │   ├── backtrace.cpp
│   │   ├── backtrace.h
│   │   ├── demo.cpp
│   │   ├── error.cpp
│   │   ├── error.h
│   │   ├── handlers.cpp
│   │   ├── handlers.h
│   │   ├── stackanalyzer.cpp
│   │   └── stackanalyzer.h
│   ├── event/
│   │   ├── CMakeLists.txt
│   │   ├── demo/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── aicontroller.cpp
│   │   │   ├── aicontroller.h
│   │   │   ├── gamestate.cpp
│   │   │   ├── gamestate.h
│   │   │   ├── gui.cpp
│   │   │   ├── gui.h
│   │   │   ├── main.cpp
│   │   │   ├── main.h
│   │   │   ├── physics.cpp
│   │   │   └── physics.h
│   │   ├── event.cpp
│   │   ├── event.h
│   │   ├── event_loop.cpp
│   │   ├── event_loop.h
│   │   ├── evententity.cpp
│   │   ├── evententity.h
│   │   ├── eventhandler.cpp
│   │   ├── eventhandler.h
│   │   ├── eventqueue.cpp
│   │   ├── eventqueue.h
│   │   ├── eventstore.cpp
│   │   ├── eventstore.h
│   │   ├── state.cpp
│   │   ├── state.h
│   │   └── tests.cpp
│   ├── gamestate/
│   │   ├── CMakeLists.txt
│   │   ├── activity/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── activity.cpp
│   │   │   ├── activity.h
│   │   │   ├── condition/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── command_in_queue.cpp
│   │   │   │   ├── command_in_queue.h
│   │   │   │   ├── next_command.cpp
│   │   │   │   └── next_command.h
│   │   │   ├── end_node.cpp
│   │   │   ├── end_node.h
│   │   │   ├── event/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── command_in_queue.cpp
│   │   │   │   ├── command_in_queue.h
│   │   │   │   ├── wait.cpp
│   │   │   │   └── wait.h
│   │   │   ├── node.cpp
│   │   │   ├── node.h
│   │   │   ├── start_node.cpp
│   │   │   ├── start_node.h
│   │   │   ├── task_node.cpp
│   │   │   ├── task_node.h
│   │   │   ├── task_system_node.cpp
│   │   │   ├── task_system_node.h
│   │   │   ├── tests.cpp
│   │   │   ├── types.cpp
│   │   │   ├── types.h
│   │   │   ├── xor_event_gate.cpp
│   │   │   ├── xor_event_gate.h
│   │   │   ├── xor_gate.cpp
│   │   │   └── xor_gate.h
│   │   ├── api/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── ability.cpp
│   │   │   ├── ability.h
│   │   │   ├── activity.cpp
│   │   │   ├── activity.h
│   │   │   ├── animation.cpp
│   │   │   ├── animation.h
│   │   │   ├── definitions.cpp
│   │   │   ├── definitions.h
│   │   │   ├── patch.cpp
│   │   │   ├── patch.h
│   │   │   ├── player_setup.cpp
│   │   │   ├── player_setup.h
│   │   │   ├── property.cpp
│   │   │   ├── property.h
│   │   │   ├── sound.cpp
│   │   │   ├── sound.h
│   │   │   ├── terrain.cpp
│   │   │   ├── terrain.h
│   │   │   ├── types.cpp
│   │   │   ├── types.h
│   │   │   ├── util.cpp
│   │   │   └── util.h
│   │   ├── component/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── api/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── idle.cpp
│   │   │   │   ├── idle.h
│   │   │   │   ├── live.cpp
│   │   │   │   ├── live.h
│   │   │   │   ├── move.cpp
│   │   │   │   ├── move.h
│   │   │   │   ├── selectable.cpp
│   │   │   │   ├── selectable.h
│   │   │   │   ├── turn.cpp
│   │   │   │   └── turn.h
│   │   │   ├── api_component.cpp
│   │   │   ├── api_component.h
│   │   │   ├── base_component.cpp
│   │   │   ├── base_component.h
│   │   │   ├── internal/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── activity.cpp
│   │   │   │   ├── activity.h
│   │   │   │   ├── command_queue.cpp
│   │   │   │   ├── command_queue.h
│   │   │   │   ├── commands/
│   │   │   │   │   ├── CMakeLists.txt
│   │   │   │   │   ├── base_command.cpp
│   │   │   │   │   ├── base_command.h
│   │   │   │   │   ├── custom.cpp
│   │   │   │   │   ├── custom.h
│   │   │   │   │   ├── idle.cpp
│   │   │   │   │   ├── idle.h
│   │   │   │   │   ├── move.cpp
│   │   │   │   │   ├── move.h
│   │   │   │   │   ├── types.cpp
│   │   │   │   │   └── types.h
│   │   │   │   ├── ownership.cpp
│   │   │   │   ├── ownership.h
│   │   │   │   ├── position.cpp
│   │   │   │   └── position.h
│   │   │   ├── internal_component.cpp
│   │   │   ├── internal_component.h
│   │   │   ├── types.cpp
│   │   │   └── types.h
│   │   ├── definitions.cpp
│   │   ├── definitions.h
│   │   ├── demo/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── demo_0.cpp
│   │   │   ├── demo_0.h
│   │   │   ├── tests.cpp
│   │   │   └── tests.h
│   │   ├── entity_factory.cpp
│   │   ├── entity_factory.h
│   │   ├── event/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── drag_select.cpp
│   │   │   ├── drag_select.h
│   │   │   ├── process_command.cpp
│   │   │   ├── process_command.h
│   │   │   ├── send_command.cpp
│   │   │   ├── send_command.h
│   │   │   ├── spawn_entity.cpp
│   │   │   ├── spawn_entity.h
│   │   │   ├── wait.cpp
│   │   │   └── wait.h
│   │   ├── game.cpp
│   │   ├── game.h
│   │   ├── game_entity.cpp
│   │   ├── game_entity.h
│   │   ├── game_state.cpp
│   │   ├── game_state.h
│   │   ├── manager.cpp
│   │   ├── manager.h
│   │   ├── map.cpp
│   │   ├── map.h
│   │   ├── player.cpp
│   │   ├── player.h
│   │   ├── simulation.cpp
│   │   ├── simulation.h
│   │   ├── system/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── activity.cpp
│   │   │   ├── activity.h
│   │   │   ├── idle.cpp
│   │   │   ├── idle.h
│   │   │   ├── move.cpp
│   │   │   ├── move.h
│   │   │   ├── types.cpp
│   │   │   └── types.h
│   │   ├── terrain.cpp
│   │   ├── terrain.h
│   │   ├── terrain_chunk.cpp
│   │   ├── terrain_chunk.h
│   │   ├── terrain_factory.cpp
│   │   ├── terrain_factory.h
│   │   ├── terrain_tile.cpp
│   │   ├── terrain_tile.h
│   │   ├── types.cpp
│   │   ├── types.h
│   │   ├── universe.cpp
│   │   ├── universe.h
│   │   ├── world.cpp
│   │   └── world.h
│   ├── input/
│   │   ├── CMakeLists.txt
│   │   ├── action.cpp
│   │   ├── action.h
│   │   ├── controller/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── camera/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── binding.cpp
│   │   │   │   ├── binding.h
│   │   │   │   ├── binding_context.cpp
│   │   │   │   ├── binding_context.h
│   │   │   │   ├── controller.cpp
│   │   │   │   └── controller.h
│   │   │   ├── game/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── binding.cpp
│   │   │   │   ├── binding.h
│   │   │   │   ├── binding_context.cpp
│   │   │   │   ├── binding_context.h
│   │   │   │   ├── controller.cpp
│   │   │   │   └── controller.h
│   │   │   └── hud/
│   │   │       ├── CMakeLists.txt
│   │   │       ├── binding.cpp
│   │   │       ├── binding.h
│   │   │       ├── binding_context.cpp
│   │   │       ├── binding_context.h
│   │   │       ├── controller.cpp
│   │   │       └── controller.h
│   │   ├── event.cpp
│   │   ├── event.h
│   │   ├── input_context.cpp
│   │   ├── input_context.h
│   │   ├── input_manager.cpp
│   │   ├── input_manager.h
│   │   ├── tests.cpp
│   │   ├── text_to_event.cpp
│   │   └── text_to_event.h
│   ├── job/
│   │   ├── CMakeLists.txt
│   │   ├── abortable_job_state.h
│   │   ├── job.h
│   │   ├── job_aborted_exception.h
│   │   ├── job_group.cpp
│   │   ├── job_group.h
│   │   ├── job_manager.cpp
│   │   ├── job_manager.h
│   │   ├── job_state.h
│   │   ├── job_state_base.h
│   │   ├── tests.cpp
│   │   ├── typed_job_state_base.h
│   │   ├── types.h
│   │   ├── worker.cpp
│   │   └── worker.h
│   ├── log/
│   │   ├── CMakeLists.txt
│   │   ├── file_logsink.cpp
│   │   ├── file_logsink.h
│   │   ├── level.cpp
│   │   ├── level.h
│   │   ├── log.cpp
│   │   ├── log.h
│   │   ├── logsink.cpp
│   │   ├── logsink.h
│   │   ├── logsource.cpp
│   │   ├── logsource.h
│   │   ├── message.cpp
│   │   ├── message.h
│   │   ├── named_logsource.cpp
│   │   ├── named_logsource.h
│   │   ├── stdout_logsink.cpp
│   │   ├── stdout_logsink.h
│   │   └── test.cpp
│   ├── main/
│   │   ├── CMakeLists.txt
│   │   ├── demo/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── interactive/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── interactive.cpp
│   │   │   │   └── interactive.h
│   │   │   ├── pong/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── aicontroller.cpp
│   │   │   │   ├── aicontroller.h
│   │   │   │   ├── gamestate.cpp
│   │   │   │   ├── gamestate.h
│   │   │   │   ├── gui.cpp
│   │   │   │   ├── gui.h
│   │   │   │   ├── physics.cpp
│   │   │   │   ├── physics.h
│   │   │   │   ├── pong.cpp
│   │   │   │   └── pong.h
│   │   │   └── presenter/
│   │   │       ├── CMakeLists.txt
│   │   │       ├── presenter.cpp
│   │   │       └── presenter.h
│   │   ├── tests.cpp
│   │   └── tests.h
│   ├── main.cpp
│   ├── main.h
│   ├── options.cpp
│   ├── options.h
│   ├── pathfinding/
│   │   ├── CMakeLists.txt
│   │   ├── cost_field.cpp
│   │   ├── cost_field.h
│   │   ├── definitions.cpp
│   │   ├── definitions.h
│   │   ├── demo/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── demo_0.cpp
│   │   │   ├── demo_0.h
│   │   │   ├── demo_1.cpp
│   │   │   ├── demo_1.h
│   │   │   ├── tests.cpp
│   │   │   └── tests.h
│   │   ├── field_cache.cpp
│   │   ├── field_cache.h
│   │   ├── flow_field.cpp
│   │   ├── flow_field.h
│   │   ├── grid.cpp
│   │   ├── grid.h
│   │   ├── integration_field.cpp
│   │   ├── integration_field.h
│   │   ├── integrator.cpp
│   │   ├── integrator.h
│   │   ├── legacy/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── a_star.cpp
│   │   │   ├── a_star.h
│   │   │   ├── heuristics.cpp
│   │   │   ├── heuristics.h
│   │   │   ├── path.cpp
│   │   │   ├── path.h
│   │   │   ├── path_utils.h
│   │   │   └── tests.cpp
│   │   ├── path.cpp
│   │   ├── path.h
│   │   ├── pathfinder.cpp
│   │   ├── pathfinder.h
│   │   ├── portal.cpp
│   │   ├── portal.h
│   │   ├── sector.cpp
│   │   ├── sector.h
│   │   ├── tests.cpp
│   │   ├── types.cpp
│   │   └── types.h
│   ├── presenter/
│   │   ├── CMakeLists.txt
│   │   ├── presenter.cpp
│   │   └── presenter.h
│   ├── pyinterface/
│   │   ├── CMakeLists.txt
│   │   ├── defs.cpp
│   │   ├── defs.h
│   │   ├── exctranslate.cpp
│   │   ├── exctranslate.h
│   │   ├── exctranslate_tests.cpp
│   │   ├── exctranslate_tests.h
│   │   ├── functional.cpp
│   │   ├── functional.h
│   │   ├── hacks.cpp
│   │   ├── hacks.h
│   │   ├── pyexception.cpp
│   │   ├── pyexception.h
│   │   ├── pyobject.cpp
│   │   ├── pyobject.h
│   │   ├── pyobject_tests.cpp
│   │   ├── pyobject_tests.h
│   │   ├── setup.cpp
│   │   └── setup.h
│   ├── renderer/
│   │   ├── CMakeLists.txt
│   │   ├── camera/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── boundaries.cpp
│   │   │   ├── boundaries.h
│   │   │   ├── camera.cpp
│   │   │   ├── camera.h
│   │   │   ├── definitions.cpp
│   │   │   ├── definitions.h
│   │   │   ├── frustum_2d.cpp
│   │   │   ├── frustum_2d.h
│   │   │   ├── frustum_3d.cpp
│   │   │   └── frustum_3d.h
│   │   ├── color.cpp
│   │   ├── color.h
│   │   ├── definitions.cpp
│   │   ├── definitions.h
│   │   ├── demo/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── demo_0.cpp
│   │   │   ├── demo_0.h
│   │   │   ├── demo_1.cpp
│   │   │   ├── demo_1.h
│   │   │   ├── demo_2.cpp
│   │   │   ├── demo_2.h
│   │   │   ├── demo_3.cpp
│   │   │   ├── demo_3.h
│   │   │   ├── demo_4.cpp
│   │   │   ├── demo_4.h
│   │   │   ├── demo_5.cpp
│   │   │   ├── demo_5.h
│   │   │   ├── demo_6.cpp
│   │   │   ├── demo_6.h
│   │   │   ├── demo_7.cpp
│   │   │   ├── demo_7.h
│   │   │   ├── stresstest_0.cpp
│   │   │   ├── stresstest_0.h
│   │   │   ├── stresstest_1.cpp
│   │   │   ├── stresstest_1.h
│   │   │   ├── tests.cpp
│   │   │   ├── tests.h
│   │   │   ├── util.cpp
│   │   │   └── util.h
│   │   ├── font/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── font.cpp
│   │   │   ├── font.h
│   │   │   ├── font_manager.cpp
│   │   │   ├── font_manager.h
│   │   │   ├── glyph_atlas.cpp
│   │   │   ├── glyph_atlas.h
│   │   │   └── tests.cpp
│   │   ├── geometry.cpp
│   │   ├── geometry.h
│   │   ├── gui/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── gui.cpp
│   │   │   ├── gui.h
│   │   │   ├── guisys/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── link/
│   │   │   │   │   ├── gui_item.cpp
│   │   │   │   │   ├── gui_item.h
│   │   │   │   │   ├── gui_item_link.h
│   │   │   │   │   ├── gui_item_list_model.h
│   │   │   │   │   ├── gui_list_model.cpp
│   │   │   │   │   ├── gui_list_model.h
│   │   │   │   │   ├── gui_property_map_impl.cpp
│   │   │   │   │   ├── gui_property_map_impl.h
│   │   │   │   │   ├── gui_singleton_item.cpp
│   │   │   │   │   ├── gui_singleton_item.h
│   │   │   │   │   └── qtgui_checked_static_cast.h
│   │   │   │   ├── private/
│   │   │   │   │   ├── gui_application_impl.cpp
│   │   │   │   │   ├── gui_application_impl.h
│   │   │   │   │   ├── gui_ctx_setup.cpp
│   │   │   │   │   ├── gui_ctx_setup.h
│   │   │   │   │   ├── gui_engine_impl.cpp
│   │   │   │   │   ├── gui_engine_impl.h
│   │   │   │   │   ├── gui_input_impl.cpp
│   │   │   │   │   ├── gui_input_impl.h
│   │   │   │   │   ├── gui_renderer_impl.cpp
│   │   │   │   │   ├── gui_renderer_impl.h
│   │   │   │   │   ├── gui_rendering_setup_routines.cpp
│   │   │   │   │   ├── gui_rendering_setup_routines.h
│   │   │   │   │   ├── gui_subtree_impl.cpp
│   │   │   │   │   ├── gui_subtree_impl.h
│   │   │   │   │   ├── livereload/
│   │   │   │   │   │   ├── deferred_initial_constant_property_values.cpp
│   │   │   │   │   │   ├── deferred_initial_constant_property_values.h
│   │   │   │   │   │   ├── gui_live_reloader.cpp
│   │   │   │   │   │   ├── gui_live_reloader.h
│   │   │   │   │   │   ├── recursive_directory_watcher.cpp
│   │   │   │   │   │   ├── recursive_directory_watcher.h
│   │   │   │   │   │   ├── recursive_directory_watcher_worker.cpp
│   │   │   │   │   │   └── recursive_directory_watcher_worker.h
│   │   │   │   │   ├── opengl_debug_logger.cpp
│   │   │   │   │   └── opengl_debug_logger.h
│   │   │   │   └── public/
│   │   │   │       ├── gui_application.cpp
│   │   │   │       ├── gui_application.h
│   │   │   │       ├── gui_engine.cpp
│   │   │   │       ├── gui_engine.h
│   │   │   │       ├── gui_input.cpp
│   │   │   │       ├── gui_input.h
│   │   │   │       ├── gui_renderer.cpp
│   │   │   │       ├── gui_renderer.h
│   │   │   │       ├── gui_subtree.cpp
│   │   │   │       └── gui_subtree.h
│   │   │   └── integration/
│   │   │       ├── CMakeLists.txt
│   │   │       ├── private/
│   │   │       │   ├── CMakeLists.txt
│   │   │       │   ├── gui_filled_texture_handles.cpp
│   │   │       │   ├── gui_filled_texture_handles.h
│   │   │       │   ├── gui_log.cpp
│   │   │       │   ├── gui_log.h
│   │   │       │   ├── gui_make_standalone_subtexture.cpp
│   │   │       │   ├── gui_make_standalone_subtexture.h
│   │   │       │   ├── gui_standalone_subtexture.cpp
│   │   │       │   ├── gui_standalone_subtexture.h
│   │   │       │   ├── gui_texture.cpp
│   │   │       │   ├── gui_texture.h
│   │   │       │   ├── gui_texture_handle.cpp
│   │   │       │   └── gui_texture_handle.h
│   │   │       └── public/
│   │   │           ├── CMakeLists.txt
│   │   │           ├── gui_application_with_logger.cpp
│   │   │           └── gui_application_with_logger.h
│   │   ├── opengl/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── buffer.cpp
│   │   │   ├── buffer.h
│   │   │   ├── context.cpp
│   │   │   ├── context.h
│   │   │   ├── debug.cpp
│   │   │   ├── debug.h
│   │   │   ├── error.cpp
│   │   │   ├── error.h
│   │   │   ├── framebuffer.cpp
│   │   │   ├── framebuffer.h
│   │   │   ├── geometry.cpp
│   │   │   ├── geometry.h
│   │   │   ├── lookup.h
│   │   │   ├── render_pass.cpp
│   │   │   ├── render_pass.h
│   │   │   ├── render_target.cpp
│   │   │   ├── render_target.h
│   │   │   ├── renderer.cpp
│   │   │   ├── renderer.h
│   │   │   ├── shader.cpp
│   │   │   ├── shader.h
│   │   │   ├── shader_data.cpp
│   │   │   ├── shader_data.h
│   │   │   ├── shader_program.cpp
│   │   │   ├── shader_program.h
│   │   │   ├── simple_object.cpp
│   │   │   ├── simple_object.h
│   │   │   ├── texture.cpp
│   │   │   ├── texture.h
│   │   │   ├── texture_array.cpp
│   │   │   ├── texture_array.h
│   │   │   ├── uniform_buffer.cpp
│   │   │   ├── uniform_buffer.h
│   │   │   ├── uniform_input.cpp
│   │   │   ├── uniform_input.h
│   │   │   ├── util.cpp
│   │   │   ├── util.h
│   │   │   ├── vertex_array.cpp
│   │   │   ├── vertex_array.h
│   │   │   ├── window.cpp
│   │   │   └── window.h
│   │   ├── render_factory.cpp
│   │   ├── render_factory.h
│   │   ├── render_pass.cpp
│   │   ├── render_pass.h
│   │   ├── render_target.cpp
│   │   ├── render_target.h
│   │   ├── renderable.cpp
│   │   ├── renderable.h
│   │   ├── renderer.cpp
│   │   ├── renderer.h
│   │   ├── resources/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── animation/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── angle_info.cpp
│   │   │   │   ├── angle_info.h
│   │   │   │   ├── animation_info.cpp
│   │   │   │   ├── animation_info.h
│   │   │   │   ├── frame_info.cpp
│   │   │   │   ├── frame_info.h
│   │   │   │   ├── layer_info.cpp
│   │   │   │   └── layer_info.h
│   │   │   ├── assets/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── asset_manager.cpp
│   │   │   │   ├── asset_manager.h
│   │   │   │   ├── cache.cpp
│   │   │   │   ├── cache.h
│   │   │   │   ├── texture_manager.cpp
│   │   │   │   └── texture_manager.h
│   │   │   ├── buffer_info.cpp
│   │   │   ├── buffer_info.h
│   │   │   ├── frame_timing.cpp
│   │   │   ├── frame_timing.h
│   │   │   ├── mesh_data.cpp
│   │   │   ├── mesh_data.h
│   │   │   ├── palette_info.cpp
│   │   │   ├── palette_info.h
│   │   │   ├── parser/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── common.cpp
│   │   │   │   ├── common.h
│   │   │   │   ├── parse_blendmask.cpp
│   │   │   │   ├── parse_blendmask.h
│   │   │   │   ├── parse_blendtable.cpp
│   │   │   │   ├── parse_blendtable.h
│   │   │   │   ├── parse_palette.cpp
│   │   │   │   ├── parse_palette.h
│   │   │   │   ├── parse_sprite.cpp
│   │   │   │   ├── parse_sprite.h
│   │   │   │   ├── parse_terrain.cpp
│   │   │   │   ├── parse_terrain.h
│   │   │   │   ├── parse_texture.cpp
│   │   │   │   └── parse_texture.h
│   │   │   ├── shader_source.cpp
│   │   │   ├── shader_source.h
│   │   │   ├── shader_template.cpp
│   │   │   ├── shader_template.h
│   │   │   ├── terrain/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── blendpattern_info.cpp
│   │   │   │   ├── blendpattern_info.h
│   │   │   │   ├── blendtable_info.cpp
│   │   │   │   ├── blendtable_info.h
│   │   │   │   ├── frame_info.cpp
│   │   │   │   ├── frame_info.h
│   │   │   │   ├── layer_info.cpp
│   │   │   │   ├── layer_info.h
│   │   │   │   ├── terrain_info.cpp
│   │   │   │   └── terrain_info.h
│   │   │   ├── texture_data.cpp
│   │   │   ├── texture_data.h
│   │   │   ├── texture_info.cpp
│   │   │   ├── texture_info.h
│   │   │   ├── texture_subinfo.cpp
│   │   │   └── texture_subinfo.h
│   │   ├── shader_program.cpp
│   │   ├── shader_program.h
│   │   ├── stages/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── camera/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── manager.cpp
│   │   │   │   └── manager.h
│   │   │   ├── hud/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── object.cpp
│   │   │   │   ├── object.h
│   │   │   │   ├── render_entity.cpp
│   │   │   │   ├── render_entity.h
│   │   │   │   ├── render_stage.cpp
│   │   │   │   └── render_stage.h
│   │   │   ├── render_entity.cpp
│   │   │   ├── render_entity.h
│   │   │   ├── screen/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── render_stage.cpp
│   │   │   │   ├── render_stage.h
│   │   │   │   ├── screenshot.cpp
│   │   │   │   └── screenshot.h
│   │   │   ├── skybox/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── render_stage.cpp
│   │   │   │   └── render_stage.h
│   │   │   ├── terrain/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── chunk.cpp
│   │   │   │   ├── chunk.h
│   │   │   │   ├── mesh.cpp
│   │   │   │   ├── mesh.h
│   │   │   │   ├── model.cpp
│   │   │   │   ├── model.h
│   │   │   │   ├── render_entity.cpp
│   │   │   │   ├── render_entity.h
│   │   │   │   ├── render_stage.cpp
│   │   │   │   └── render_stage.h
│   │   │   └── world/
│   │   │       ├── CMakeLists.txt
│   │   │       ├── object.cpp
│   │   │       ├── object.h
│   │   │       ├── render_entity.cpp
│   │   │       ├── render_entity.h
│   │   │       ├── render_stage.cpp
│   │   │       └── render_stage.h
│   │   ├── texture.cpp
│   │   ├── texture.h
│   │   ├── texture_array.cpp
│   │   ├── texture_array.h
│   │   ├── types.cpp
│   │   ├── types.h
│   │   ├── uniform_buffer.cpp
│   │   ├── uniform_buffer.h
│   │   ├── uniform_input.cpp
│   │   ├── uniform_input.h
│   │   ├── util.cpp
│   │   ├── util.h
│   │   ├── vulkan/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── README.md
│   │   │   ├── graphics_device.cpp
│   │   │   ├── graphics_device.h
│   │   │   ├── loader.cpp
│   │   │   ├── loader.h
│   │   │   ├── render_target.h
│   │   │   ├── renderer.cpp
│   │   │   ├── renderer.h
│   │   │   ├── shader_program.h
│   │   │   ├── util.h
│   │   │   ├── windowvk.cpp
│   │   │   └── windowvk.h
│   │   ├── window.cpp
│   │   ├── window.h
│   │   ├── window_event_handler.cpp
│   │   └── window_event_handler.h
│   ├── rng/
│   │   ├── CMakeLists.txt
│   │   ├── global_rng.cpp
│   │   ├── global_rng.h
│   │   ├── rng.cpp
│   │   ├── rng.h
│   │   └── rng_tests.cpp
│   ├── testing/
│   │   ├── CMakeLists.txt
│   │   ├── benchmark_test.cpp
│   │   ├── testing.cpp
│   │   ├── testing.h
│   │   ├── testlist.cpp.template
│   │   └── testlist.h
│   ├── time/
│   │   ├── CMakeLists.txt
│   │   ├── clock.cpp
│   │   ├── clock.h
│   │   ├── time.cpp
│   │   ├── time.h
│   │   ├── time_loop.cpp
│   │   └── time_loop.h
│   ├── util/
│   │   ├── CMakeLists.txt
│   │   ├── algorithm.h
│   │   ├── color.cpp
│   │   ├── color.h
│   │   ├── compiler.cpp
│   │   ├── compiler.h
│   │   ├── compress/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── bitstream.h
│   │   │   ├── lzxd.cpp
│   │   │   └── lzxd.h
│   │   ├── consteval.h
│   │   ├── constinit_vector.cpp
│   │   ├── constinit_vector.h
│   │   ├── enum.cpp
│   │   ├── enum.h
│   │   ├── enum_test.cpp
│   │   ├── enum_test.h
│   │   ├── externalprofiler.cpp
│   │   ├── externalprofiler.h
│   │   ├── externalsstream.cpp
│   │   ├── externalsstream.h
│   │   ├── fds.cpp
│   │   ├── fds.h
│   │   ├── file.cpp
│   │   ├── file.h
│   │   ├── filelike/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── filelike.cpp
│   │   │   ├── filelike.h
│   │   │   ├── native.cpp
│   │   │   ├── native.h
│   │   │   ├── python.cpp
│   │   │   └── python.h
│   │   ├── fixed_point.cpp
│   │   ├── fixed_point.h
│   │   ├── fixed_point_test.cpp
│   │   ├── fps.cpp
│   │   ├── fps.h
│   │   ├── fslike/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── directory.cpp
│   │   │   ├── directory.h
│   │   │   ├── fslike.cpp
│   │   │   ├── fslike.h
│   │   │   ├── native.cpp
│   │   │   ├── native.h
│   │   │   ├── python.cpp
│   │   │   └── python.h
│   │   ├── hash.cpp
│   │   ├── hash.h
│   │   ├── hash_test.cpp
│   │   ├── init.cpp
│   │   ├── init.h
│   │   ├── language.cpp
│   │   ├── language.h
│   │   ├── macro/
│   │   │   ├── concat.h
│   │   │   └── loop.h
│   │   ├── math.h
│   │   ├── math_constants.h
│   │   ├── matrix.cpp
│   │   ├── matrix.h
│   │   ├── matrix_test.cpp
│   │   ├── misc.cpp
│   │   ├── misc.h
│   │   ├── misc_test.cpp
│   │   ├── os.cpp
│   │   ├── os.h
│   │   ├── path.cpp
│   │   ├── path.h
│   │   ├── pty.h
│   │   ├── quaternion.cpp
│   │   ├── quaternion.h
│   │   ├── quaternion_test.cpp
│   │   ├── repr.cpp
│   │   ├── repr.h
│   │   ├── signal.h
│   │   ├── stringformatter.cpp
│   │   ├── stringformatter.h
│   │   ├── strings.cpp
│   │   ├── strings.h
│   │   ├── subprocess.cpp
│   │   ├── subprocess.h
│   │   ├── thread_id.cpp
│   │   ├── thread_id.h
│   │   ├── timer.cpp
│   │   ├── timer.h
│   │   ├── timing.cpp
│   │   ├── timing.h
│   │   ├── unicode.cpp
│   │   ├── unicode.h
│   │   ├── variable.h
│   │   ├── vector.cpp
│   │   ├── vector.h
│   │   └── vector_test.cpp
│   ├── version.cpp.in
│   ├── version.h.in
│   └── versions/
│       ├── CMakeLists.txt
│       ├── compiletime.cpp.in
│       ├── compiletime.h.in
│       ├── versions.cpp
│       └── versions.h
├── nix/
│   ├── nyan.nix
│   └── openage.nix
├── openage/
│   ├── .gitignore
│   ├── CMakeLists.txt
│   ├── __init__.py
│   ├── __main__.py
│   ├── assets.py
│   ├── cabextract/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── cab.py
│   │   ├── cabchecksum.pyx
│   │   ├── gen_test_arc.sh
│   │   ├── lzxd.pyx
│   │   ├── lzxdstream.py
│   │   └── test.py
│   ├── codegen/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── codegen.py
│   │   ├── coord.py
│   │   ├── cpp_testlist.py
│   │   ├── listing.py
│   │   └── main.py
│   ├── config.py.in
│   ├── convert/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── entity_object/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── __init__.py
│   │   │   ├── conversion/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── __init__.py
│   │   │   │   ├── aoc/
│   │   │   │   │   ├── CMakeLists.txt
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── genie_civ.py
│   │   │   │   │   ├── genie_connection.py
│   │   │   │   │   ├── genie_effect.py
│   │   │   │   │   ├── genie_graphic.py
│   │   │   │   │   ├── genie_object_container.py
│   │   │   │   │   ├── genie_sound.py
│   │   │   │   │   ├── genie_tech.py
│   │   │   │   │   ├── genie_terrain.py
│   │   │   │   │   └── genie_unit.py
│   │   │   │   ├── combined_sound.py
│   │   │   │   ├── combined_sprite.py
│   │   │   │   ├── combined_terrain.py
│   │   │   │   ├── converter_object.py
│   │   │   │   ├── modpack.py
│   │   │   │   ├── ror/
│   │   │   │   │   ├── CMakeLists.txt
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── genie_sound.py
│   │   │   │   │   ├── genie_tech.py
│   │   │   │   │   └── genie_unit.py
│   │   │   │   ├── stringresource.py
│   │   │   │   └── swgbcc/
│   │   │   │       ├── CMakeLists.txt
│   │   │   │       ├── __init__.py
│   │   │   │       ├── genie_tech.py
│   │   │   │       └── genie_unit.py
│   │   │   └── export/
│   │   │       ├── CMakeLists.txt
│   │   │       ├── __init__.py
│   │   │       ├── data_definition.py
│   │   │       ├── formats/
│   │   │       │   ├── CMakeLists.txt
│   │   │       │   ├── __init__.py
│   │   │       │   ├── blmask_metadata.py
│   │   │       │   ├── bltable_metadata.py
│   │   │       │   ├── media_cache.py
│   │   │       │   ├── modpack_info.py
│   │   │       │   ├── modpack_manifest.py
│   │   │       │   ├── nyan_file.py
│   │   │       │   ├── palette_metadata.py
│   │   │       │   ├── sprite_metadata.py
│   │   │       │   ├── terrain_metadata.py
│   │   │       │   └── texture_metadata.py
│   │   │       ├── media_export_request.py
│   │   │       ├── metadata_export.py
│   │   │       └── texture.py
│   │   ├── main.py
│   │   ├── processor/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── __init__.py
│   │   │   ├── conversion/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── __init__.py
│   │   │   │   ├── aoc/
│   │   │   │   │   ├── CMakeLists.txt
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── ability_subprocessor.py
│   │   │   │   │   ├── auxiliary_subprocessor.py
│   │   │   │   │   ├── civ_subprocessor.py
│   │   │   │   │   ├── effect_subprocessor.py
│   │   │   │   │   ├── media_subprocessor.py
│   │   │   │   │   ├── modifier_subprocessor.py
│   │   │   │   │   ├── modpack_subprocessor.py
│   │   │   │   │   ├── nyan_subprocessor.py
│   │   │   │   │   ├── pregen_processor.py
│   │   │   │   │   ├── processor.py
│   │   │   │   │   ├── tech_subprocessor.py
│   │   │   │   │   ├── upgrade_ability_subprocessor.py
│   │   │   │   │   ├── upgrade_attribute_subprocessor.py
│   │   │   │   │   ├── upgrade_effect_subprocessor.py
│   │   │   │   │   └── upgrade_resource_subprocessor.py
│   │   │   │   ├── aoc_demo/
│   │   │   │   │   ├── CMakeLists.txt
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── modpack_subprocessor.py
│   │   │   │   │   └── processor.py
│   │   │   │   ├── de1/
│   │   │   │   │   ├── CMakeLists.txt
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── media_subprocessor.py
│   │   │   │   │   ├── modpack_subprocessor.py
│   │   │   │   │   └── processor.py
│   │   │   │   ├── de2/
│   │   │   │   │   ├── CMakeLists.txt
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── ability_subprocessor.py
│   │   │   │   │   ├── civ_subprocessor.py
│   │   │   │   │   ├── media_subprocessor.py
│   │   │   │   │   ├── modpack_subprocessor.py
│   │   │   │   │   ├── nyan_subprocessor.py
│   │   │   │   │   ├── processor.py
│   │   │   │   │   ├── tech_subprocessor.py
│   │   │   │   │   ├── upgrade_attribute_subprocessor.py
│   │   │   │   │   └── upgrade_resource_subprocessor.py
│   │   │   │   ├── hd/
│   │   │   │   │   ├── CMakeLists.txt
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── media_subprocessor.py
│   │   │   │   │   ├── modpack_subprocessor.py
│   │   │   │   │   └── processor.py
│   │   │   │   ├── ror/
│   │   │   │   │   ├── CMakeLists.txt
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── ability_subprocessor.py
│   │   │   │   │   ├── auxiliary_subprocessor.py
│   │   │   │   │   ├── civ_subprocessor.py
│   │   │   │   │   ├── media_subprocessor.py
│   │   │   │   │   ├── modpack_subprocessor.py
│   │   │   │   │   ├── nyan_subprocessor.py
│   │   │   │   │   ├── pregen_subprocessor.py
│   │   │   │   │   ├── processor.py
│   │   │   │   │   ├── tech_subprocessor.py
│   │   │   │   │   ├── upgrade_ability_subprocessor.py
│   │   │   │   │   ├── upgrade_attribute_subprocessor.py
│   │   │   │   │   └── upgrade_resource_subprocessor.py
│   │   │   │   └── swgbcc/
│   │   │   │       ├── CMakeLists.txt
│   │   │   │       ├── __init__.py
│   │   │   │       ├── ability_subprocessor.py
│   │   │   │       ├── auxiliary_subprocessor.py
│   │   │   │       ├── civ_subprocessor.py
│   │   │   │       ├── modpack_subprocessor.py
│   │   │   │       ├── nyan_subprocessor.py
│   │   │   │       ├── pregen_subprocessor.py
│   │   │   │       ├── processor.py
│   │   │   │       ├── tech_subprocessor.py
│   │   │   │       ├── upgrade_attribute_subprocessor.py
│   │   │   │       └── upgrade_resource_subprocessor.py
│   │   │   └── export/
│   │   │       ├── CMakeLists.txt
│   │   │       ├── __init__.pxd
│   │   │       ├── __init__.py
│   │   │       ├── data_exporter.py
│   │   │       ├── generate_manifest_hashes.py
│   │   │       ├── media_exporter.py
│   │   │       ├── modpack_exporter.py
│   │   │       ├── terrain_merge.pyx
│   │   │       └── texture_merge.pyx
│   │   ├── service/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── __init__.py
│   │   │   ├── conversion/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── __init__.py
│   │   │   │   └── internal_name_lookups.py
│   │   │   ├── debug_info.py
│   │   │   ├── export/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── __init__.py
│   │   │   │   ├── interface/
│   │   │   │   │   ├── CMakeLists.txt
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── cutter.py
│   │   │   │   │   ├── rename.py
│   │   │   │   │   └── visgrep.pyx
│   │   │   │   ├── load_media_cache.py
│   │   │   │   ├── opus/
│   │   │   │   │   ├── CMakeLists.txt
│   │   │   │   │   ├── __init__.pxd
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── bytearray.pxd
│   │   │   │   │   ├── demo.py
│   │   │   │   │   ├── ogg.pxd
│   │   │   │   │   ├── opus.pxd
│   │   │   │   │   └── opusenc.pyx
│   │   │   │   └── png/
│   │   │   │       ├── CMakeLists.txt
│   │   │   │       ├── __init__.pxd
│   │   │   │       ├── __init__.py
│   │   │   │       ├── binpack.pxd
│   │   │   │       ├── binpack.pyx
│   │   │   │       ├── libpng.pxd
│   │   │   │       ├── png_create.pyx
│   │   │   │       └── png_tmp_file.pxd
│   │   │   ├── init/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── __init__.py
│   │   │   │   ├── api_export_required.py
│   │   │   │   ├── changelog.py
│   │   │   │   ├── modpack_search.py
│   │   │   │   ├── mount_asset_dirs.py
│   │   │   │   └── version_detect.py
│   │   │   └── read/
│   │   │       ├── CMakeLists.txt
│   │   │       ├── __init__.py
│   │   │       ├── gamedata.py
│   │   │       ├── nyan_api_loader.py
│   │   │       ├── palette.py
│   │   │       ├── register_media.py
│   │   │       └── string_resource.py
│   │   ├── tool/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── __init__.py
│   │   │   ├── api_export.py
│   │   │   ├── driver.py
│   │   │   ├── interactive.py
│   │   │   ├── singlefile.py
│   │   │   └── subtool/
│   │   │       ├── CMakeLists.txt
│   │   │       ├── __init__.py
│   │   │       ├── acquire_sourcedir.py
│   │   │       └── version_select.py
│   │   └── value_object/
│   │       ├── CMakeLists.txt
│   │       ├── __init__.py
│   │       ├── conversion/
│   │       │   ├── CMakeLists.txt
│   │       │   ├── __init__.py
│   │       │   ├── aoc/
│   │       │   │   ├── CMakeLists.txt
│   │       │   │   ├── __init__.py
│   │       │   │   └── internal_nyan_names.py
│   │       │   ├── de1/
│   │       │   │   ├── CMakeLists.txt
│   │       │   │   ├── __init__.py
│   │       │   │   └── internal_nyan_names.py
│   │       │   ├── de2/
│   │       │   │   ├── CMakeLists.txt
│   │       │   │   ├── __init__.py
│   │       │   │   └── internal_nyan_names.py
│   │       │   ├── forward_ref.py
│   │       │   ├── hd/
│   │       │   │   ├── CMakeLists.txt
│   │       │   │   ├── __init__.py
│   │       │   │   ├── ak/
│   │       │   │   │   ├── CMakeLists.txt
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   └── internal_nyan_names.py
│   │       │   │   ├── fgt/
│   │       │   │   │   ├── CMakeLists.txt
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   └── internal_nyan_names.py
│   │       │   │   └── raj/
│   │       │   │       ├── CMakeLists.txt
│   │       │   │       ├── __init__.py
│   │       │   │       └── internal_nyan_names.py
│   │       │   ├── ror/
│   │       │   │   ├── CMakeLists.txt
│   │       │   │   ├── __init__.py
│   │       │   │   └── internal_nyan_names.py
│   │       │   └── swgb/
│   │       │       ├── CMakeLists.txt
│   │       │       ├── __init__.py
│   │       │       └── internal_nyan_names.py
│   │       ├── init/
│   │       │   ├── CMakeLists.txt
│   │       │   ├── __init__.py
│   │       │   ├── game_file_version.py
│   │       │   └── game_version.py
│   │       └── read/
│   │           ├── CMakeLists.txt
│   │           ├── __init__.py
│   │           ├── dynamic_loader.py
│   │           ├── genie_structure.py
│   │           ├── media/
│   │           │   ├── CMakeLists.txt
│   │           │   ├── __init__.pxd
│   │           │   ├── __init__.py
│   │           │   ├── blendomatic.py
│   │           │   ├── colortable.py
│   │           │   ├── datfile/
│   │           │   │   ├── CMakeLists.txt
│   │           │   │   ├── __init__.py
│   │           │   │   ├── civ.py
│   │           │   │   ├── empiresdat.py
│   │           │   │   ├── graphic.py
│   │           │   │   ├── lookup_dicts.py
│   │           │   │   ├── maps.py
│   │           │   │   ├── playercolor.py
│   │           │   │   ├── research.py
│   │           │   │   ├── sound.py
│   │           │   │   ├── tech.py
│   │           │   │   ├── terrain.py
│   │           │   │   └── unit.py
│   │           │   ├── drs.py
│   │           │   ├── hardcoded/
│   │           │   │   ├── CMakeLists.txt
│   │           │   │   ├── __init__.py
│   │           │   │   ├── interface.py
│   │           │   │   ├── termcolors.py
│   │           │   │   ├── terrain_tile_size.py
│   │           │   │   └── texture.py
│   │           │   ├── langcodes.py
│   │           │   ├── pefile.py
│   │           │   ├── peresource.py
│   │           │   ├── sld.pyx
│   │           │   ├── slp.pyx
│   │           │   ├── smp.pyx
│   │           │   └── smx.pyx
│   │           ├── media_types.py
│   │           ├── member_access.py
│   │           ├── read_members.py
│   │           └── value_members.py
│   ├── cppinterface/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── exctranslate.pyx
│   │   ├── exctranslate_tests.pyx
│   │   ├── pyobject.pyx
│   │   ├── setup.py
│   │   ├── setup_checker.pyx
│   │   └── typedefs.pxd
│   ├── cvar/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── config_file.py
│   │   ├── cvar.pyx
│   │   └── location.py
│   ├── cython_check.pyx
│   ├── default_dirs.py
│   ├── devmode.py
│   ├── event/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   └── demo.pyx
│   ├── game/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── main.py
│   │   └── main_cpp.pyx
│   ├── gamestate/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   └── tests.pyx
│   ├── log/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── log_cpp.pyx
│   │   └── tests.py
│   ├── main/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── main.py
│   │   ├── main_cpp.pyx
│   │   └── tests.pyx
│   ├── nyan/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── import_tree.py
│   │   └── nyan_structs.py
│   ├── pathfinding/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   └── tests.pyx
│   ├── renderer/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── renderer_cpp.pyx
│   │   └── tests.pyx
│   ├── testing/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── benchmark.py
│   │   ├── cpp_testing.pyx
│   │   ├── doctest.py
│   │   ├── list_processor.py
│   │   ├── main.py
│   │   ├── misc_cpp.pyx
│   │   ├── testing.py
│   │   └── testlist.py
│   ├── util/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── bytequeue.py
│   │   ├── context.py
│   │   ├── decorators.py
│   │   ├── dll.py
│   │   ├── filelike/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── __init__.py
│   │   │   ├── abstract.py
│   │   │   ├── cpp.pyx
│   │   │   ├── fifo.py
│   │   │   ├── readonly.py
│   │   │   └── stream.py
│   │   ├── files.py
│   │   ├── fslike/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── __init__.py
│   │   │   ├── abstract.py
│   │   │   ├── cpp.pxd
│   │   │   ├── cpp.pyx
│   │   │   ├── directory.py
│   │   │   ├── filecollection.py
│   │   │   ├── path.py
│   │   │   ├── test.py
│   │   │   ├── union.py
│   │   │   └── wrapper.py
│   │   ├── fsprinting.py
│   │   ├── hash.py
│   │   ├── iterators.py
│   │   ├── math.py
│   │   ├── observer.py
│   │   ├── ordered_set.py
│   │   ├── profiler.py
│   │   ├── strings.py
│   │   ├── struct.py
│   │   ├── system.py
│   │   ├── threading.py
│   │   └── version.py
│   └── versions/
│       ├── CMakeLists.txt
│       ├── __init__.py
│       └── versions.pyx
├── openage_version
├── packaging/
│   ├── CMakeLists.txt
│   ├── CPackOptions.cmake
│   └── docker/
│       └── devenv/
│           └── Dockerfile.ubuntu.2404
├── run.py.in
└── shell.nix

================================================
FILE CONTENTS
================================================

================================================
FILE: .clang-format
================================================
---
# SFT codestyle
# Tab indent + space alignment
# see documentation in doc/code_style/ for details and explainations.
Language:        Cpp
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignArrayOfStructures: None
AlignConsecutiveAssignments: false
AlignConsecutiveBitFields: false
AlignConsecutiveDeclarations: false
AlignConsecutiveMacros: false
AlignEscapedNewlines: DontAlign
AlignOperands:   Align
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
  AfterCaseLabel:  false
  AfterClass:      false
  AfterControlStatement: Never
  AfterEnum:       false
  AfterExternBlock: false
  AfterFunction:   false
  AfterNamespace:  false
  AfterObjCDeclaration: false
  AfterStruct:     false
  AfterUnion:      false
  BeforeCatch:     true
  BeforeElse:      true
  BeforeLambdaBody: false
  BeforeWhile:     true
  IndentBraces:    false
  SplitEmptyFunction: false
  SplitEmptyNamespace: false
  SplitEmptyRecord: false
BreakAfterJavaFieldAnnotations: true
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: false
BreakConstructorInitializers: AfterColon
BreakInheritanceList: BeforeComma
BreakStringLiterals: false
ColumnLimit:     0
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat:   false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
  - foreach
  - Q_FOREACH
  - BOOST_FOREACH
IncludeBlocks:   Preserve
IncludeCategories:
  - Regex:           '.*'
    Priority:        3
    SortPriority:    0
IncludeIsMainRegex: ''
IncludeIsMainSourceRegex: ''
IndentCaseBlocks: false
IndentCaseLabels: false
IndentExternBlock: NoIndent
IndentGotoLabels: false
IndentPPDirectives: BeforeHash
IndentWidth:     4
IndentWrappedFunctionNames: false
# clang-format-16 InsertNewlineAtEOF: true
InsertTrailingCommas: Wrapped
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd:   ''
MaxEmptyLinesToKeep: 2
NamespaceIndentation: None
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Right
ReflowComments: true
SortIncludes:    CaseInsensitive
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles:  Never
SpacesInCStyleCastParentheses: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard:        Latest
TabWidth:        4
UseCRLF:         false
UseTab:          AlignWithSpaces
...


================================================
FILE: .github/PULL_REQUEST_TEMPLATES/pull_request_template.md
================================================
### Merge Checklist

<!-- Complete all tasks below to make sure that we can merge your pull request. -->
<!-- If you are an experienced contributor, you may delete this section ;-) -->

- [ ] I have read the [contribution guide](doc/contributing.md)
- [ ] I have added my info to [copying.md](copying.md) (only first time contributors)
- [ ] I have run `make checkmerge` and fixed all mentioned problems


### Description

<!-- Describe the changes this pull request makes to the code base. -->


================================================
FILE: .github/PULL_REQUEST_TEMPLATES/release_template.md
================================================
### Checklist

- [ ] Changelog
    - [ ] Release date
    - [ ] Version number in title
    - [ ] Full commit log
- [ ] Bump version in `openage_version`


================================================
FILE: .github/workflows/macosx-ci.yml
================================================
name: macOS-CI
on: [push, pull_request]

jobs:
  # https://docs.github.com/en/actions/reference/software-installed-on-github-hosted-runners
  # we install stuff not already there
  macos-build:
    runs-on: macos-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v4

      # caching dependencies and ccache
      # https://docs.github.com/en/actions/configuring-and-managing-workflows/caching-dependencies-to-speed-up-workflows
      - name: Get timestamp
        id: timestamp
        shell: cmake -P {0}
        run: |
          string(TIMESTAMP current_date "%Y-%m-%d-%H:%M:%S" UTC)
          message("timestamp=${current_date}" >> $GITHUB_OUTPUT)
      - name: Cache dependencies
        uses: actions/cache@v4
        id: cache-deps
        with:
          path: |
            ~/Library/Caches/pip
            ~/Library/Caches/Homebrew
          key: '${{ runner.os }}-deps-${{ steps.timestamp.outputs.timestamp }}'
          restore-keys: |
            ${{ runner.os }}-deps-
      - name: Cache ccache dir
        uses: actions/cache@v4
        id: cache-ccache
        with:
          path: ~/Library/Caches/ccache
          key: '${{ runner.os }}-ccache-${{ steps.timestamp.outputs.timestamp }}'
          restore-keys: |
            ${{ runner.os }}-ccache-
      - name: Brew update-reset
        run: brew update-reset
      - name: Brew update
        run: brew update
      - name: Brew install DeJaVu fonts
        run: brew install --cask font-dejavu
      - name: Install environment helpers with homebrew
        run: brew install --force ccache
      - name: Install LLVM with homebrew
        run: brew install --force llvm
      - name: Install openage dependencies with homebrew
        run: brew install --force cmake python3 libepoxy freetype fontconfig harfbuzz opus opusfile qt6 libogg libpng toml11 eigen
      - name: Install nyan dependencies with homebrew
        run: brew install --force flex make
      - name: Install python3 packages
        # cython, numpy and pygments are in homebrew,
        # but "cython is keg-only, which means it was not symlinked into /usr/local"
        # numpy pulls gcc as dep? and pygments doesn't work.
        run: pip3 install --upgrade --break-system-packages cython numpy mako lz4 pillow pygments setuptools toml
      - name: Configure
        run: ./configure --compiler="$(brew --prefix llvm)/bin/clang++" --mode=release --ccache --download-nyan
      - name: Build
        run: make -j$(sysctl -n hw.logicalcpu) VERBOSE=1
      - name: Test
        run: make test


================================================
FILE: .github/workflows/ubuntu-24.04.yml
================================================
name: Ubuntu 24.04 CI

on: [push, workflow_dispatch]

jobs:
  build-devenv:
    runs-on: ubuntu-24.04
    steps:
    - uses: actions/checkout@v4
    - name: Build the Docker image
      run: sudo DOCKER_BUILDKIT=1 docker build ./packaging/docker/devenv --file ./packaging/docker/devenv/Dockerfile.ubuntu.2404 --tag openage-devenv:latest
      shell: bash
    - name: Save the Docker image
      run: |
        mkdir -p /tmp/staging
        sudo docker save openage-devenv:latest | gzip > /tmp/staging/devenv.tar.gz
      shell: bash
    - name: Publish the Docker image
      uses: actions/upload-artifact@v4
      with:
        name: devenv-image-compressed.tar.gz
        path: '/tmp/staging/devenv.tar.gz'
        if-no-files-found: error
        retention-days: 30

  build:
    runs-on: ubuntu-24.04
    needs: build-devenv
    steps:
    - uses: actions/checkout@v4
    - name: Create tmp path
      run: mkdir -p /tmp/image
      shell: bash
    - name: Download devenv image
      uses: actions/download-artifact@v4
      with:
        name: devenv-image-compressed.tar.gz
        path: '/tmp/image'
    - name: Load Docker image
      run: sudo docker load --input /tmp/image/devenv.tar.gz
    - name: Build openage
      run: |
        sudo docker run --rm -v "$(pwd)":/mnt/openage -w /mnt/openage openage-devenv:latest \
          bash -c 'mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=$(which gcc) -DCMAKE_CXX_COMPILER=$(which g++) -DCMAKE_CXX_FLAGS='' -DCMAKE_EXE_LINKER_FLAGS='' -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_MODULE_LINKER_FLAGS='' -DCMAKE_SHARED_LINKER_FLAGS='' -DDOWNLOAD_NYAN=YES -DCXX_OPTIMIZATION_LEVEL=auto -DCXX_SANITIZE_FATAL=False -DCXX_SANITIZE_MODE=none -DWANT_BACKTRACE=if_available -DWANT_GPERFTOOLS_PROFILER=if_available -DWANT_GPERFTOOLS_TCMALLOC=False -DWANT_INOTIFY=if_available -DWANT_NCURSES=if_available -DWANT_OPENGL=if_available -DWANT_VULKAN=if_available -G Ninja .. && cmake --build . --parallel $(nproc) -- -k1'
    - name: Compress build artifacts
      run: |
        mkdir -p /tmp/openage
        tar -czvf /tmp/openage/openage-build.tar.gz ./build
    - name: Publish build artifacts
      uses: actions/upload-artifact@v4
      with:
        name: openage-build.tar.gz
        path: '/tmp/openage/openage-build.tar.gz'
        if-no-files-found: error
        retention-days: 30


================================================
FILE: .github/workflows/windows-server-2019.yml
================================================
name: Windows Server 2019 CI

on: [push, workflow_dispatch]

jobs:
  build-x64:
    runs-on: windows-2019
    steps:
    - uses: actions/checkout@v4
      with:
        submodules: recursive
        path: source
    - name: Inspect environment
      run: |
        vswhere -latest
      shell: pwsh
    - name: Setup Python
      uses: actions/setup-python@v5
      with:
        python-version: '3.9'
        architecture: 'x64'
    - name: Install dependencies [vcpkg]
      run: |
        mkdir download
        cd download
        $zipfile = "openage-dep-x64-windows.zip"
        Invoke-WebRequest https://github.com/SFTtech/openage-dependencies/releases/download/v0.5.1/openage-dep-x64-windows.zip -OutFile $zipfile
        Expand-Archive -Path $zipfile -DestinationPath . -Force
        Remove-Item $zipfile
        (Get-ChildItem . -Recurse -File).FullName
      shell: pwsh
    - name: Install dependencies [winflexbison]
      run: |
        cd download
        $zipfile = "winflexbison-2.5.24.zip"
        Invoke-WebRequest https://github.com/lexxmark/winflexbison/releases/download/v2.5.24/win_flex_bison-2.5.24.zip -OutFile $zipfile
        mkdir winflexbison
        Expand-Archive -Path $zipfile -DestinationPath ./winflexbison -Force
        Remove-Item $zipfile
        (Get-ChildItem ./winflexbison -Recurse -File).FullName
      shell: pwsh
    - name: Install dependencies [Python]
      run: |
        python -m pip install --upgrade pip
        python -m pip install --upgrade Cython wheel numpy lz4 toml pillow pygments pyreadline3 mako
      shell: pwsh
    - name: Build
      run: |
        $TOOLCHAIN_FILE = Join-Path download openage-dep-x64-windows scripts buildsystems vcpkg.cmake | Resolve-Path
        $FLEX_PATH = (Get-ChildItem ./download -Recurse -Force -Filter 'win_flex.exe')[0].FullName
        mkdir build
        cd build
        cmake -DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN_FILE" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TRY_COMPILE_CONFIGURATION=Debug -DCMAKE_CXX_FLAGS='/Zc:__cplusplus /permissive- /EHsc' -DCMAKE_EXE_LINKER_FLAGS='' -DCMAKE_MODULE_LINKER_FLAGS='' -DCMAKE_SHARED_LINKER_FLAGS='' -DDOWNLOAD_NYAN=YES -DCXX_OPTIMIZATION_LEVEL=auto -DCXX_SANITIZE_FATAL=False -DCXX_SANITIZE_MODE=none -DWANT_BACKTRACE=if_available -DWANT_GPERFTOOLS_PROFILER=if_available -DWANT_GPERFTOOLS_TCMALLOC=False -DWANT_INOTIFY=if_available -DWANT_NCURSES=if_available -DWANT_OPENGL=if_available -DWANT_VULKAN=if_available -DFLEX_EXECUTABLE="$FLEX_PATH" -G "Visual Studio 16 2019" -A x64 ../source
        cmake --build . --config Debug -- -nologo -maxCpuCount
      shell: pwsh
    - name: Package
      run: |
        mkdir package
        cd package
        mkdir dll
        cd ..
        $STAGING_PATH = Resolve-Path package
        $DLL_PATH = Join-Path package dll | Resolve-Path

        cd build
        $NYAN_DLL = (Get-ChildItem . -Recurse -Force -Filter 'nyan.dll')[0].FullName
        $OPENAGE_DLL = (Get-ChildItem . -Recurse -Force -Filter 'openage.dll')[0].FullName
        $NATIVE_OUTPUT = Split-Path -Path $OPENAGE_DLL -Parent
        Copy-Item -Path ./openage -Destination $STAGING_PATH -Recurse
        Copy-Item -Path $NYAN_DLL -Destination $DLL_PATH
        Copy-Item -Path (Join-Path $NATIVE_OUTPUT *.dll) -Destination $DLL_PATH
        Copy-Item -Path run.* -Destination $STAGING_PATH
      shell: pwsh
    - name: Test
      run: |
        $DLL_PATH = Join-Path package dll | Resolve-Path
        cd package
        python -m openage --add-dll-search-path $DLL_PATH --version
        python -m openage --add-dll-search-path $DLL_PATH test -a
      shell: pwsh
    - name: Publish build artifacts
      uses: actions/upload-artifact@v4
      if: ${{ always() }}
      with:
        name: build-files
        path: './build'
        if-no-files-found: error
        retention-days: 30
    - name: Publish packaged artifacts
      uses: actions/upload-artifact@v4
      if: ${{ always() }}
      with:
        name: package-files
        path: './package'
        if-no-files-found: error
        retention-days: 30


================================================
FILE: .github/workflows/windows-server-2022.yml
================================================
name: Windows Server 2022 CI

on: [push, workflow_dispatch]

jobs:
  build-x64:
    runs-on: windows-2022
    steps:
    - uses: actions/checkout@v4
      with:
        submodules: recursive
        path: source
    - name: Inspect environment
      run: |
        vswhere -latest
      shell: pwsh
    - name: Setup Python
      uses: actions/setup-python@v5
      with:
        python-version: '3.9'
        architecture: 'x64'
    - name: Install dependencies [vcpkg]
      run: |
        mkdir download
        cd download
        $zipfile = "openage-dep-x64-windows.zip"
        Invoke-WebRequest https://github.com/SFTtech/openage-dependencies/releases/download/v0.5.1/openage-dep-x64-windows.zip -OutFile $zipfile
        Expand-Archive -Path $zipfile -DestinationPath . -Force
        Remove-Item $zipfile
        (Get-ChildItem . -Recurse -File).FullName
      shell: pwsh
    - name: Install dependencies [winflexbison]
      run: |
        cd download
        $zipfile = "winflexbison-2.5.24.zip"
        Invoke-WebRequest https://github.com/lexxmark/winflexbison/releases/download/v2.5.24/win_flex_bison-2.5.24.zip -OutFile $zipfile
        mkdir winflexbison
        Expand-Archive -Path $zipfile -DestinationPath ./winflexbison -Force
        Remove-Item $zipfile
        (Get-ChildItem ./winflexbison -Recurse -File).FullName
      shell: pwsh
    - name: Install dependencies [Python]
      run: |
        python -m pip install --upgrade pip
        python -m pip install --upgrade Cython wheel numpy lz4 toml pillow pygments pyreadline3 mako
      shell: pwsh
    - name: Build
      run: |
        $TOOLCHAIN_FILE = Join-Path download openage-dep-x64-windows scripts buildsystems vcpkg.cmake | Resolve-Path
        $FLEX_PATH = (Get-ChildItem ./download -Recurse -Force -Filter 'win_flex.exe')[0].FullName
        mkdir build
        cd build
        cmake -DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN_FILE" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TRY_COMPILE_CONFIGURATION=Debug -DCMAKE_CXX_FLAGS='/Zc:__cplusplus /permissive- /EHsc' -DCMAKE_EXE_LINKER_FLAGS='' -DCMAKE_MODULE_LINKER_FLAGS='' -DCMAKE_SHARED_LINKER_FLAGS='' -DDOWNLOAD_NYAN=YES -DCXX_OPTIMIZATION_LEVEL=auto -DCXX_SANITIZE_FATAL=False -DCXX_SANITIZE_MODE=none -DWANT_BACKTRACE=if_available -DWANT_GPERFTOOLS_PROFILER=if_available -DWANT_GPERFTOOLS_TCMALLOC=False -DWANT_INOTIFY=if_available -DWANT_NCURSES=if_available -DWANT_OPENGL=if_available -DWANT_VULKAN=if_available -DFLEX_EXECUTABLE="$FLEX_PATH" -G "Visual Studio 17 2022" -A x64 ../source
        cmake --build . --config Debug -- -nologo -maxCpuCount
      shell: pwsh
    - name: Package
      run: |
        mkdir package
        cd package
        mkdir dll
        cd ..
        $STAGING_PATH = Resolve-Path package
        $DLL_PATH = Join-Path package dll | Resolve-Path

        cd build
        $NYAN_DLL = (Get-ChildItem . -Recurse -Force -Filter 'nyan.dll')[0].FullName
        $OPENAGE_DLL = (Get-ChildItem . -Recurse -Force -Filter 'openage.dll')[0].FullName
        $NATIVE_OUTPUT = Split-Path -Path $OPENAGE_DLL -Parent
        Copy-Item -Path ./openage -Destination $STAGING_PATH -Recurse
        Copy-Item -Path $NYAN_DLL -Destination $DLL_PATH
        Copy-Item -Path (Join-Path $NATIVE_OUTPUT *.dll) -Destination $DLL_PATH
        Copy-Item -Path run.* -Destination $STAGING_PATH
      shell: pwsh
    - name: Test
      run: |
        $DLL_PATH = Join-Path package dll | Resolve-Path
        cd package
        python -m openage --add-dll-search-path $DLL_PATH --version
        python -m openage --add-dll-search-path $DLL_PATH test -a
      shell: pwsh
    - name: Publish build artifacts
      uses: actions/upload-artifact@v4
      if: ${{ always() }}
      with:
        name: build-files
        path: './build'
        if-no-files-found: error
        retention-days: 30
    - name: Publish packaged artifacts
      uses: actions/upload-artifact@v4
      if: ${{ always() }}
      with:
        name: package-files
        path: './package'
        if-no-files-found: error
        retention-days: 30


================================================
FILE: .gitignore
================================================
# editor-specific files
\#*
.#*
*~
.*.swp
/CMakeLists.txt.user
*.temp

# ELF files
*.o
*.a
*.so

# python bytecode
*.pyc
*.pyo
__pycache__
*.pyd

# MSVC files
*.pdb
*.dll
*.exe

# workflow
*.orig
/TODO.org

# build system
/bin
/.bin
/build
/deps
/.ccls-cache
/.cache

# Nix build output
/result

# root dir run script
/run
/run.cpp
/run.html

# CMake in-source builds
/DartConfiguration.tcl
/codegen_depend_cache
/codegen_target_cache
/Doxyfile
/Testing
/py/setup.py
CTestTestfile.cmake
CMakeFiles
cmake_install.cmake
CMakeCache.txt
Makefile
!/Makefile

# debugging
callgrind.out.*
perf.data*
.gdb_history

# code search
/.ignore
/.globalrc
/GPATH
/GRTAGS
/GTAGS

# IDEs
.vscode
.idea

# CMake + ccls
/compile_commands.json

# Virtual Environments
/.venv/

# macOS
.DS_Store

# copyrighted assets
/assets/converted/
/assets/terrain/


================================================
FILE: .mailmap
================================================
Michael Enßlin <michael@ensslin.cc>
Jonas Jelten <jj@sft.lol> <jonas.jelten@gmail.com>
Jonas Jelten <jj@sft.lol> <jelten@in.tum.de>
Jonas Jelten <jj@sft.lol> <jj@sft.mx>
Renée Kooi <renee@kooi.me> <renekooi@outlook.com>
Renée Kooi <renee@kooi.me> <rene@kooi.me>
Ingo Saftbaumer <?> <matthias@bogad.at>
Ingo Saftbaumer <?> <matthias.bogad@tum.de>
James Mintram <jamesmintram@gmail.com> <james@lemonmoosegames.com>
Sam Schetterer <samschet@gmail.com> <schets@users.noreply.github.com>
Jimmy Berry <jimmy@boombatower.com>
Jonathan Remnant <jono4728@gmail.com>
Henry Snoek <?> <snoek09@users.noreply.github.com>
coop shell (Michael Enßlin, Jonas Jelten, Andre Kupka) <coop@sft.mx>
Franz-Niclas Muschter <fm@stusta.net> <franz-niclas.muschter@stusta.net>
Niklas Fiekas <niklas.fiekas@backscattering.de> <niklas.fiekas@tu-clausthal.de>
Wojciech Nawrocki <wjnawrocki@protonmail.com> <wjnawrocki+gh@protonmail.com>
Simon San <?> <14062932+simonsan@users.noreply.github.com>
Tobias Feldballe <tobias@osandweb.dk> <tobi.fp@gmail.com>
Tobias Feldballe <tobias@osandweb.dk> <tf@jumpstory.com>
Jonas Borchelt <jonas.borchelt@connected.link>
Derek Frogget <fro22003@byui.edu> <114030121+derekfrogget@users.noreply.github.com>
Nikhil Ghosh <nghosh606@gmail.com>
David Wever <dmwever@crimson.ua.edu> <56411717+dmwever@users.noreply.github.com>
Ngô Xuân Minh <xminh.ngo.00@gmail.com>


================================================
FILE: CMakeLists.txt
================================================
# Copyright 2013-2023 the openage authors. See copying.md for legal info.

# >=3.16 finding numpy with the findpython3 module
cmake_minimum_required(VERSION 3.16)


# main build configuration file

# text art: figlet -f rounded "[SFT] openage" | sed -e 's/\\/\\\\/g'
message("

 ___  ______ _______ _______ ___
|  _)/ _____|_______|_______|_  |
| | ( (____  _____      _     | |    ___  ____  _____ ____  _____  ____ _____
| |  \\____ \\|  ___)    | |    | |   / _ \\|  _ \\| ___ |  _ \\(____ |/ _  | ___ |
| |_ _____) ) |        | |   _| |  | |_| | |_| | ____| | | / ___ ( (_| | ____|
|___|______/|_|        |_|  (___|   \\___/|  __/|_____)_| |_\\_____|\\___ |_____)
                                         |_|                     (_____|

Welcome to the SFT technologies computer-aided openage build system!

You have chosen, or been chosen, to attempt the daring task of building openage.
If you have installed all the dependencies that are conveniently listed in
[doc/building.md], this _might_ just work!

If it doesn't, consider reporting the issue, or ask for help:
  * GitHub: https://github.com/SFTtech/openage
  * Matrix: #sfttech:matrix.org
")


##################################################
# main buildsystem setup entry point
project(openage CXX)

# C++ standard requirement
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Python and Cython requirements
set(PYTHON_MIN_VERSION 3.9)
set(CYTHON_MIN_VERSION 3.0.10)
set(CYTHON_MIN_VERSION_FALLBACK 0.29.31)
set(CYTHON_MAX_VERSION_FALLBACK 3.0.7)

# CMake policies
foreach(pol
        CMP0074  # use <pkg>_ROOT vars in find_package()
        CMP0067  # honor language standard in try_compile()
        CMP0071  # enable automoc for generated files
        CMP0072  # prefers GLVND by default FindOpenGL
        CMP0048  # project() command manages VERSION variables
        CMP0094  # take the first satisfying Python version
        CMP0082  # run add_subdirectory() in the declaration order
        CMP0102  # Don't create empty cache entries
       )
	if (POLICY ${pol})
		cmake_policy(SET ${pol} NEW)
	endif()
endforeach()

# don't print 'Built target ...' messages
# upstream since cmake v3.4.0-rc1 (by commit 1d3984780df8)
set_property(GLOBAL PROPERTY TARGET_MESSAGES OFF)

# Ensure CMAKE_BUILD_TYPE is set correctly.
if(NOT CMAKE_BUILD_TYPE)
	set(CMAKE_BUILD_TYPE "Debug")
endif()
string(TOUPPER "CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}" BUILD_TYPE_CXX_FLAGS)


##################################################
# options: keep up to date with those in ./configure!
if(NOT DEFINED WANT_BACKTRACE)
	set(WANT_BACKTRACE if_available)
endif()

if(NOT DEFINED WANT_INOTIFY)
	set(WANT_INOTIFY if_available)
endif()

if(NOT DEFINED WANT_OPENGL)
	set(WANT_OPENGL if_available)
endif()

if(NOT DEFINED WANT_VULKAN)
	set(WANT_VULKAN if_available)
endif()

if(NOT DEFINED WANT_GPERFTOOLS_PROFILER)
	set(WANT_GPERFTOOLS_PROFILER if_available)
endif()

if(NOT DEFINED WANT_GPERFTOOLS_TCMALLOC)
	set(WANT_GPERFTOOLS_TCMALLOC false)
endif()

if(NOT DEFINED WANT_NCURSES)
	set(WANT_NCURSES if_available)
endif()

if(NOT DEFINED WANT_IWYU)
	set(WANT_IWYU false)
endif()

##################################################
# static content filesystem locations
if(NOT DEFINED GLOBAL_ASSET_DIR)
	set(ASSET_DIR "share/openage")
	if(MSVC)
		set(GLOBAL_ASSET_DIR "${ASSET_DIR}")
	else()
		set(GLOBAL_ASSET_DIR "${CMAKE_INSTALL_PREFIX}/${ASSET_DIR}")
	endif()
endif()

if(NOT DEFINED GLOBAL_CONFIG_DIR)
	set(CONFIG_DIR "etc/openage")
	if(MSVC)
		set(GLOBAL_CONFIG_DIR "${CONFIG_DIR}")
	else()
		set(GLOBAL_CONFIG_DIR "${CMAKE_INSTALL_PREFIX}/${CONFIG_DIR}")
	endif()
endif()


##################################################
# ccache setup

# distros can also do this but they don't use this mechanism
option(ENABLE_CCACHE "prefix each compile command with ccache")

if(ENABLE_CCACHE)
	find_program(CCACHE_FOUND "ccache")

	if(CCACHE_FOUND)
		set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
		set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
	else()
		message(FATAL_ERROR "ccache not found, but you requested it")
	endif(CCACHE_FOUND)
endif()


##################################################
# clang tidy static analysis
option(
	ENABLE_CLANG_TIDY
	"activate clang tidy messages"
	OFF
)
if(ENABLE_CLANG_TIDY)
	set(CMAKE_CXX_CLANG_TIDY "clang-tidy;-checks=-*,readability-*")
endif()


# option processing is now done.

##################################################
# include buildsystem features

# add search paths to helper modules
set(BUILDSYSTEM_DIR "${CMAKE_SOURCE_DIR}/buildsystem")
set(CMAKE_MODULE_PATH "${BUILDSYSTEM_DIR}" "${BUILDSYSTEM_DIR}/modules/")

# prioritize macOS frameworks since they're probably newer
# than the system libraries
set(CMAKE_FIND_FRAMEWORK LAST)
set(CMAKE_FIND_APPBUNDLE LAST)

# load helper modules
include(GNUInstallDirs)
include(CheckInSourceBuild)
include(HandleCXXOptions)
include(CheckCompilerFeatures)
include(CMakeParseArguments)
include(HandlePythonOptions)
include(CheckRuntimeDependencies)
include(DetectProjectVersion)
include(DependencyFetch)
include(FindPackageHandleStandardArgs)

# include build configuration modules
include(CTest)

# initialize language support
include(codegen)
include(cpp)
include(doxygen)
include(options)
include(python)
include(util)


# now that all modules and settings are loaded,
# apply those to the project.


##################################################
# set project version
if(USED_GIT_VERSION)
	# VERSION_FULL_STRING is the full git describe
	set(VERSION_FULL_STRING "${PROJECT_VERSION}")
	# PROJECT_VERSION is MAJOR.MINOR.PATCH.TWEAK with Commit-Count as Tweak
	STRING(REGEX REPLACE "v(([0-9]+.|[0-9]+)+)-([0-9]+)-g([a-f0-9]+)"
			"\\1.\\3" PROJECT_VERSION "${VERSION_FULL_STRING}")
endif()
project(openage VERSION "${PROJECT_VERSION}")

# set CI version
if(DEFINED ENV{CI_CFG_VERSION})
    set(CI_CFG_VERSION "$ENV{CI_CFG_VERSION}")
else()
    set(CI_CFG_VERSION "NOT SET")
endif()


##################################################
# documentation generation

# create documentation
doxygen_configure(libopenage/ openage/ doc/ README.md)


##################################################
# static content
add_subdirectory(assets/)
add_subdirectory(dist/)
add_subdirectory(cfg/)


##################################################
# C++ content
add_subdirectory(libopenage/)


##################################################
# Python content (uses the C++ library)

# create a virtual library that, when linked to,
# injects a header inclusion, and links to libopenage.
# -> all cython modules get our hacks included and link to libopenage.
add_library(pyext_libopenage INTERFACE)
if(MSVC)
	set(FORCE_INCLUDE_CXXFLAG "/FI")
else()
	set(FORCE_INCLUDE_CXXFLAG "-include")
endif()
target_compile_options(pyext_libopenage INTERFACE
	${FORCE_INCLUDE_CXXFLAG} "${CMAKE_SOURCE_DIR}/libopenage/pyinterface/hacks.h"
)
target_link_libraries(pyext_libopenage INTERFACE libopenage)
set(PYEXT_LINK_LIBRARY pyext_libopenage)

configure_file(run.py.in run.py)
add_cython_modules(EMBED NOINSTALL ${CMAKE_CURRENT_BINARY_DIR}/run.py)
add_py_modules(BININSTALL ${CMAKE_CURRENT_BINARY_DIR}/run.py AS openage)
add_subdirectory(openage/)

python_finalize()


##################################################
# packaging.

# Ensure that packaging is always the last step.
add_subdirectory(packaging)


##################################################
# show build configuration overview

message("")
print_config_options()

message("${PROJECT_NAME} ${PROJECT_VERSION}

   version string | ${VERSION_FULL_STRING}
         compiler | ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}
           python | ${PYTHON_VERSION_STRING}
       build type | ${CMAKE_BUILD_TYPE}
         cxxflags | ${CMAKE_CXX_FLAGS} ${EXTRA_FLAGS}
 build type flags | ${${BUILD_TYPE_CXX_FLAGS}}
        build dir | ${CMAKE_BINARY_DIR}
   install prefix | ${CMAKE_INSTALL_PREFIX}
py install prefix | ${CMAKE_PY_INSTALL_PREFIX}
")

##################################################
# done! that was easy, right?


================================================
FILE: Makefile
================================================
# type 'make help' for a list/explaination of recipes.

BUILDDIR = bin

MAKEARGS += $(if $(VERBOSE),,--no-print-directory)

.PHONY: default
default: build

.PHONY: all
all: default

$(BUILDDIR):
	@echo "call ./configure to initialize the build directory."
	@echo "also see ./configure --help, and doc/building.md"
	@echo ""
	@false

.PHONY: install
install: $(BUILDDIR)
	$(MAKE) $(MAKEARGS) -C $(BUILDDIR) install

.PHONY: run
run: build
	cd $(BUILDDIR) && ./run main

.PHONY: test
test: tests checkfast

.PHONY: tests
tests: build
	cd $(BUILDDIR) && ./run test -a

.PHONY: build
build: $(BUILDDIR)
	@$(MAKE) $(MAKEARGS) -C $(BUILDDIR)

.PHONY: ninja
ninja: $(BUILDDIR)
	@ninja -C $(BUILDDIR)

.PHONY: libopenage
libopenage: $(BUILDDIR)
	@$(MAKE) $(MAKEARGS) -C $(BUILDDIR) libopenage

.PHONY: codegen
codegen: $(BUILDDIR)
	$(MAKE) $(MAKEARGS) -C $(BUILDDIR) cppgen

.PHONY: cppgen
cppgen: $(BUILDDIR)
	$(MAKE) $(MAKEARGS) -C $(BUILDDIR) cppgen

.PHONY: pxdgen
pxdgen: $(BUILDDIR)
	$(MAKE) $(MAKEARGS) -C $(BUILDDIR) pxdgen

.PHONY: compilepy
compilepy: $(BUILDDIR)
	$(MAKE) $(MAKEARGS) -C $(BUILDDIR) compilepy

.PHONY: inplacemodules
inplacemodules:
	$(MAKE) $(MAKEARGS) -C $(BUILDDIR) inplacemodules

.PHONY: cythonize
cythonize: $(BUILDDIR)
	$(MAKE) $(MAKEARGS) -C $(BUILDDIR) cythonize

.PHONY: doc
doc: $(BUILDDIR)
	$(MAKE) $(MAKEARGS) -C $(BUILDDIR) doc

.PHONY: cleanelf
cleanelf: $(BUILDDIR)
	@# removes all object files and binaries
	$(MAKE) $(MAKEARGS) -C $(BUILDDIR) clean

.PHONY: cleancodegen
cleancodegen: $(BUILDDIR)
	@# removes all sourcefiles created by codegen
	$(MAKE) $(MAKEARGS) -C $(BUILDDIR) cleancodegen

.PHONY: cleanpxdgen
cleanpxdgen: $(BUILDDIR)
	@# removes all generated .pxd files
	$(MAKE) $(MAKEARGS) -C $(BUILDDIR) cleanpxdgen

.PHONY: cleancython
cleancython: $(BUILDDIR)
	@# removes all .cpp files created by Cython
	$(MAKE) $(MAKEARGS) -C $(BUILDDIR) cleancython

.PHONY: clean
clean: $(BUILDDIR) cleancodegen cleanpxdgen cleancython cleanelf
	@# removes object files, binaries, py modules, generated code

.PHONY: cleaninsourcebuild
cleaninsourcebuild:
	@echo "cleaning remains of in-source builds"
	rm -rf DartConfiguration.tcl codegen_depend_cache codegen_target_cache Doxyfile Testing
	@find . -not -path "./.bin/*" -type f -name CTestTestfile.cmake              -print -delete
	@find . -not -path "./.bin/*" -type f -name cmake_install.cmake              -print -delete
	@find . -not -path "./.bin/*" -type f -name CMakeCache.txt                   -print -delete
	@find . -not -path "./.bin/*" -type f -name Makefile -not -path "./Makefile" -print -delete
	@find . -not -path "./.bin/*" -type d -name CMakeFiles                       -print -exec rm -r {} +

.PHONY: cleanbuilddirs
cleanbuilddirs: cleaninsourcebuild
	@if test -d bin; then $(MAKE) $(MAKEARGS) -C bin clean cleancython cleanpxdgen cleancodegen || true; fi
	@echo cleaning symlinks to build directories
	rm -f bin
	@echo cleaning build directories
	rm -rf .bin
	@echo cleaning cmake-time generated code
	rm -f Doxyfile py/openage/config.py libopenage/config.h libopenage/config.cpp

.PHONY: mrproper
mrproper: cleanbuilddirs
	@echo cleaning converted assets
	rm -rf userassets

.PHONY: mrproperer
mrproperer: mrproper
	@if ! test -d .git; then echo "mrproperer is only available for gitrepos."; false; fi
	@echo removing ANYTHING that is not checked into the git repo
	@echo ENTER to confirm
	@read val
	git clean -x -d -f

.PHONY: checkfast
checkfast:
	python3 -m buildsystem.codecompliance --fast

.PHONY: checkmerge
checkmerge:
	python3 -m buildsystem.codecompliance --merge

.PHONY: checkchanged
checkchanged:
	python3 -m buildsystem.codecompliance --merge --only-changed-files=origin/master

.PHONY: checkuncommited
checkuncommited:
	python3 -m buildsystem.codecompliance --merge --only-changed-files=HEAD

.PHONY: checkpy
checkpy:
	python3 -m buildsystem.codecompliance --pystyle --pylint

.PHONY: checkall
checkall:
	python3 -m buildsystem.codecompliance --all

.PHONY: help
help: $(BUILDDIR)/Makefile
	@echo "openage Makefile"
	@echo ""
	@echo "wrapper that mostly forwards recipes to the cmake-generated Makefile in bin/"
	@echo ""
	@echo "targets:"
	@echo ""
	@echo "build              -> build entire project"
	@echo "libopenage         -> build libopenage"
	@echo "pxdgen             -> generate .pxd files"
	@echo "cythonize          -> compile .pyx files to .cpp"
	@echo "compilepy          -> compile .py files to .pyc"
	@echo "inplacemodules     -> create in-place modules"
	@echo "codegen            -> generate cpp sources"
	@echo "doc                -> create documentation files"
	@echo ""
	@echo "cleanelf           -> remove C++ ELF files"
	@echo "cleancodegen       -> undo 'make codegen'"
	@echo "cleancython        -> undo 'make cythonize inplacemodules'"
	@echo "cleanpxdgen        -> undo 'make pxdgen'"
	@echo "clean              -> undo 'make' (all of the above)"
	@echo "cleanbuilddirs     -> undo 'make' and './configure'"
	@echo "cleaninsourcebuild -> undo in-source build accidents"
	@echo "mrproper           -> as above, but additionally delete user assets"
	@echo "mrproperer         -> leaves nothing but ashes"
	@echo ""
	@echo "run                -> run openage"
	@echo "tests              -> run the tests (py + cpp)"
	@echo ""
	@echo "checkall           -> full code compliance check"
	@echo "checkmerge         -> code compliance check for merging to master"
	@echo "checkfast          -> fast checks only"
	@echo "checkchanged       -> full check for all files changed since origin/master"
	@echo "checkuncommited    -> full check for all currently uncommited files"
	@echo "checkpy            -> check python compliance"
	@echo ""
	@echo "test               -> tests + checkfast. this is what you should use for regular devbuilds"
	@echo ""
	@echo "CMake help:"
	@test -d $(BUILDDIR) && $(MAKE) -C $(BUILDDIR) help || echo "no builddir is configured"


================================================
FILE: README.md
================================================
[![openage](/assets/logo/banner.svg)](http://openage.dev)
=========================================================

**openage**: a volunteer project to create a free engine clone of the *Genie Engine* used by *Age of Empires*, *Age of Empires II (HD)* and *Star Wars: Galactic Battlegrounds*, comparable to projects like [OpenMW](https://openmw.org/), [OpenRA](http://openra.net/),  [OpenSAGE](https://github.com/OpenSAGE/OpenSAGE/), [OpenTTD](https://openttd.org/) and [OpenRCT2](https://openrct2.org/).

openage uses the original game assets (such as sounds and graphics), but (for obvious reasons) doesn't ship them.
To play, you require *[any of the original games (AoE1, AoE2)](/doc/media_convert.md)* or their *Definitive Edition* releases.

[![github stars](https://img.shields.io/github/stars/SFTtech/openage.svg)](https://github.com/SFTtech/openage/stargazers)
[![#sfttech on matrix.org](/assets/doc/matrixroom.svg)](https://matrix.to/#/#sfttech:matrix.org)
[![GPL licensed](/assets/doc/license.svg)](/legal/GPLv3)


Contact
-------
| Contact          | Where?                                                                                             |
| ---------------- | -------------------------------------------------------------------------------------------------- |
| Issue Tracker    | [GitHub SFTtech/openage]                                                                           |
| Development Blog | [blog.openage.dev]                                                                                 |
| Subreddit        | [![reddit](/assets/doc/reddit.svg) /r/openage](https://www.reddit.com/r/openage/)                  |
| Discussions      | [GitHub Discussions]                                                                               |
| Matrix Chat      | [![matrix](/assets/doc/matrix.svg) `#sfttech:matrix.org`](https://matrix.to/#/#sfttech:matrix.org) |
| Money Sink       | [![money sink](/assets/doc/liberapay.svg)](https://liberapay.com/SFTtech)                          |

[GitHub SFTtech/openage]: https://github.com/SFTtech/openage/issues
[blog.openage.dev]: https://blog.openage.dev
[GitHub Discussions]: https://github.com/SFTtech/openage/discussions

Technical foundation
--------------------

| Technology   | Component                                                     |
| ------------ | ------------------------------------------------------------- |
| **C++20**    | Engine core                                                   |
| **Python3**  | Scripting, media conversion, in-game console, code generation |
| [**Cython**] | Python/C++ Glue code                                          |
| [**Qt6**]    | Graphical user interface                                      |
| [**CMake**]  | Build system                                                  |
| [**OpenGL**] | Rendering, shaders                                            |
| [**Opus**]   | Audio codec                                                   |
| [**nyan**]   | Content Configuration and Modding                             |
| [**Humans**] | Mixing together all of the above                              |

[**Cython**]: https://cython.org/
[**Qt6**]: https://contribute.qt-project.org/
[**CMake**]: https://cmake.org/
[**OpenGL**]: https://www.opengl.org/
[**Opus**]: https://opus-codec.org/
[**nyan**]: https://github.com/SFTtech/nyan
[**Humans**]: https://www.youtube.com/watch?v=fQGbXmkSArs&t=18s

Goals
-----

* Fully authentic look and feel
    * This can only be approximated since the behavior of the original game is mostly undocumented,
    and guessing/experimenting can only get you this close
    * We will not implement useless artificial limitations (max 30 selectable units...)
* An easily-moddable content format: [**nyan** yet another notation](https://github.com/SFTtech/nyan)
* An integrated Python console and API, comparable to [blender](https://www.blender.org/)
* AI scripting in Python, you can use [machine learning](http://scikit-learn.org/stable/)
    * here is some [additional literature](http://www.deeplearningbook.org/)
* Re-creating [free game assets](https://github.com/SFTtech/openage-data)
* Multiplayer (obviously)
* Matchmaking and ranking with a [haskell masterserver](https://github.com/SFTtech/openage-masterserver)
* Optionally, [improvements](/doc/ideas/) over the original game
* Awesome infrastructure such as our own [Kevin CI service](https://github.com/SFTtech/kevin)

But beware, for sanity reasons:

* No network compatibility with the original game.
  You really wanna have the same problems again?
* No binary compatibility with the original game.
  A one-way script to convert maps/savegames/missions to openage is planned though.


Current State of the Project
----------------------------

**Important notice**: At the moment, "gameplay" is basically non-functional.
We're implementing the internal game simulation (how units even do anything) with simplicity and extensibility in mind, so we had to get rid of the temporary (but kind of working) previous version.
With these changes, we can (finally) actually make use of our converted asset packs and our nyan API!
We're working day and night to make gameplay return\*.
If you're interested, we wrote detailed explanations on our blog: [Part 1](https://blog.openage.dev/new-gamestate-2020.html), [Part 2](https://blog.openage.dev/engine-core-modules.html), [Monthly Devlog](https://blog.openage.dev/tag/news.html).

*\* may not actually be every day and night*

|  Operating System   |                                                                                                       Build status                                                                                                        |
| :-----------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
|     Debian Sid      | [![Kevin CI status](https://cidata.sft.lol/openage/branches/master/status.svg)](/kevinfile) |
|  Ubuntu 24.04 LTS   |           [![Ubuntu 24.04 build status](https://github.com/SFTTech/openage/actions/workflows/ubuntu-24.04.yml/badge.svg?branch=master)](https://github.com/SFTtech/openage/actions/workflows/ubuntu-24.04.yml)            |
|        macOS        |                              [![macOS build status](https://github.com/SFTtech/openage/workflows/macOS-CI/badge.svg)](https://github.com/SFTtech/openage/actions?query=workflow%3AmacOS-CI)                               |
| Windows Server 2019 | [![Windows Server 2019 build status](https://github.com/SFTtech/openage/actions/workflows/windows-server-2019.yml/badge.svg?branch=master)](https://github.com/SFTtech/openage/actions/workflows/windows-server-2019.yml) |
| Windows Server 2022 | [![Windows Server 2022 build status](https://github.com/SFTtech/openage/actions/workflows/windows-server-2022.yml/badge.svg?branch=master)](https://github.com/SFTtech/openage/actions/workflows/windows-server-2022.yml) |

[Todo: Kevin #11]: https://github.com/SFTtech/kevin/issues/11


Installation Packages
---------------------

There are many missing parts for an actually working game.
So if you "just wanna play", [you'll be disappointed](#current-state-of-the-project), unfortunately.

We strongly recommend building the program from source to get the latest, greatest, and shiniest project state :)


* For **Linux** check at [repology](https://repology.org/project/openage/versions) if your distribution has any packages available. Otherwise, you need to build from source.
  We don't release `*.deb`, `*.rpm`, Flatpak, snap or AppImage packages yet.
* For **Windows** check our [release page](https://github.com/SFTtech/openage/releases) for the latest installer.
  Otherwise, you need to build from the source.

* For **macOS** we currently don't have any packages, you need to build from source.

If you need help, maybe our [troubleshooting guide](/doc/troubleshooting.md) helps you.


Quickstart
----------

* **How do I get this to run on my box?**
    1. [Clone](https://docs.github.com/repositories/creating-and-managing-repositories/cloning-a-repository) the repo.
    2. Install dependencies. See [doc/building.md](/doc/building.md#dependency-installation) to get instructions for your favorite platform.
    3. Build the project:
   ```
   ./configure --download-nyan
   make
   ```

**Alternative approach:**
You can build and run the project using Docker. See [Running with docker](/doc/build_instructions/docker.md) for more details.

* **I compiled everything. Now how do I run it?**
    * Execute `cd bin && ./run main`.
    * [The convert script](/doc/media_convert.md) will transform original assets into openage formats, which are a lot saner and more moddable.
    * Use your brain and react to the things you'll see.

* **Waaaaaah! It...**
    * segfaults
    * prints error messages I don't want to read
    * ate my dog

All of those are features, not bugs.

To turn them off, use `./bin/run --dont-segfault --no-errors --dont-eat-dog`.


If this still does not help, try our [troubleshooting guide](/doc/troubleshooting.md), the [contact section](#contact)
or the [bug tracker](https://github.com/SFTtech/openage/issues).

Contributing
============

You might ask yourself now "Sounds cool, but how do I participate
and ~~get famous~~ contribute useful features?".

Fortunately for you, there is a lot to do and we are very grateful for your help.

## Where do I start?

* **Check the issues** [labelled with `good first issue`](https://github.com/SFTtech/openage/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22). These are tasks that you can start right away and don't require much previous knowledge.
* **Ask us** in the [chat](https://matrix.to/#/#sfttech:matrix.org). Someone there could need
  help with something.
* You can also **take the initiative** and fix a bug you found, create an issue for discussion or
  implement a feature that we never thought of, but always wanted.


## Ok, I found something. What now?

* **[Tell us](#contact)**, if you haven't already. Chances are that we have additional information
  and directions.
* **[Read the docs](/doc)**. They will answer most "administrative"
  questions like what code style is used and how the engine core parts are connected.
* **Read the code** and get familiar with the engine component you want to work with.
* Do not hesitate to **[ask us for help](#contact)** if you do not understand something.


## How do I contribute my features/changes?

* Read the **[contributing guide](/doc/contributing.md)**.
* You can upload work-in-progress (WIP) versions or drafts of your contribution to get feedback or support.
* Tell us (again) when you want us to review your work.

## I want to help, but I'm not a programmer...

Then openage might be a good reason to become one! We have many issues and tasks for beginners. You
just have to ask and we'll find something. Alternatively, lurking is also allowed.

----

Cheers, happy hecking!


Development Process
-------------------

What does openage development look like in practice?

* extensive [synchronization](#contact)!
* [doc/development.md](/doc/development.md).

How can I help?

* [doc/contributing.md](/doc/contributing.md).

All documentation is also in this repo:

* Code documentation is embedded in the sources for Doxygen (see [doc readme](/doc/README.md)).
* Have a look at the [doc directory](/doc/). This folder tends to get outdated when code changes.


License
-------

**GNU GPLv3** or later; see [copying.md](copying.md) and [legal/GPLv3](/legal/GPLv3).

I know that probably nobody is ever gonna look at the `copying.md` file,
but if you want to contribute code to openage, please take the time to
skim through it and add yourself to the authors list.


================================================
FILE: assets/.gitignore
================================================
# converted game assets
/converted/


================================================
FILE: assets/CMakeLists.txt
================================================
# Copyright 2014-2017 the openage authors. See copying.md for legal info.

add_subdirectory(logo/)
add_subdirectory(shaders/)
add_subdirectory(test/)
add_subdirectory(textures/)

install(DIRECTORY "qml"
	DESTINATION "${ASSET_DIR}"
)

# To show QML files in the QtCreator.
file(GLOB QML_SRC "qml/*.qml")
add_custom_target(qtcreator-show-qml SOURCES ${QML_SRC})


================================================
FILE: assets/logo/CMakeLists.txt
================================================
install(
	FILES "crown.svg"
	RENAME "openage.svg"
	DESTINATION "share/pixmaps/"
)

install(
	FILES "banner.svg"
	DESTINATION "${ASSET_DIR}"
)


================================================
FILE: assets/qml/.gitignore
================================================
*.qmlc


================================================
FILE: assets/qml/Actions.qml
================================================
// Copyright 2016-2017 the openage authors. See copying.md for legal info.

import QtQuick 2.4
import QtQuick.Controls 1.1

import yay.sfttech.openage 1.0 as OA

Item {
	id: root

	/*
	 * Calls 'actionMode.act(name)' to execute actions.
	 */
	property var actionMode

	/*
	 * Use "act" properties of these objects to access the Action.
	 * Action has additional "iconCheckedSource" property.
	 */
	property alias actionObjects: actionObjectList.children

	visible: false

	ExclusiveGroup {
		id: stanceGrp
	}

	ExclusiveGroup {
		id: noGrp
	}

	Item {
		id: actionObjectList

		Repeater {
			model: OA.ActionsListModel {
				id: actionObjectListModel
				action_mode: root.actionMode
			}

			delegate: Item {
				property QtObject act: Action {
					onTriggered: root.actionMode.act(name)

					iconSource: ico != -1 ? actionObjectListModel.iconsSource + "." + ico : ""

					property url iconCheckedSource: icoChk != -1 ? actionObjectListModel.iconsSource + "." + icoChk : ""
					checkable: icoChk != -1
					exclusiveGroup: icoChk == -1 ? null : (grpID == 1) ? stanceGrp : noGrp
				}
			}
		}
	}
}


================================================
FILE: assets/qml/ActionsGrid.qml
================================================
// Copyright 2016-2017 the openage authors. See copying.md for legal info.

import QtQuick 2.4
import QtQuick.Controls 1.1

Grid {
	id: root

	/*
	 * List of actions. Fields:
	 * 'act' - button action of type 'Action' that may have 'url iconCheckedSource' property
	 *
	 * Use 'act.iconSource == ""' for gaps.
	 */
	property var buttonActions

	spacing: metricsUnit * 0.5

	Component {
		id: gridElement

		ButtonExtruded {
			property bool flat

			width: (root.height - root.spacing * (root.rows - 1)) / root.rows
			height: width

			visible: iconSource != ""

			property url iconCheckedSource
		}
	}

	Repeater {
		model: parent.buttonActions

		delegate: Loader {
			sourceComponent: gridElement
			active: typeof act !== "undefined"
			onLoaded: {
				item.iconSource = Qt.binding(function() { return act.iconSource })
				item.action = act

				item.flat = Qt.binding(function() { return act.iconSourceChecked != "" })
				item.iconCheckedSource = Qt.binding(function() { return act.iconCheckedSource })
			}
		}
	}

	/*
	 * Metric propagation.
	 */
	FontMetrics {
		id: fontMetrics
	}

	property int metricsUnit: metrics ? metrics.unit : fontMetrics.averageCharacterWidth
}


================================================
FILE: assets/qml/BindsHelp.qml
================================================
// Copyright 2015-2017 the openage authors. See copying.md for legal info.

import QtQuick 2.4
import QtQuick.Controls 1.1

import yay.sfttech.openage 1.0 as OA

Column {
	property var gameControl

	Text {
		id: dummyText
		font.pointSize: 9
	}

	Text {
		font.pointSize: dummyText.font.pointSize + 3

		color: "white"
		text: gameControl.mode ? gameControl.mode.name : "No Mode"
	}

	Repeater {
		model: gameControlObj.mode ? gameControlObj.mode.binds : undefined

		Text {
			font.pointSize: dummyText.font.pointSize
			color: "white"
			text: modelData
		}
	}

	Text {
		font.pointSize: dummyText.font.pointSize + 3

		color: "white"
		text: "Global Bindings"
	}

	Repeater {
		model: OA.Engine.globalBinds

		Text {
			font.pointSize: dummyText.font.pointSize
			color: "white"
			text: modelData
		}
	}
}


================================================
FILE: assets/qml/ButtonExtruded.qml
================================================
// Copyright 2015-2017 the openage authors. See copying.md for legal info.

import QtQuick 2.4
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.3

Button {
	style: ButtonExtrudedStyle {}
}


================================================
FILE: assets/qml/ButtonExtrudedStyle.qml
================================================
// Copyright 2015-2017 the openage authors. See copying.md for legal info.

import QtQuick 2.4
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.3

/*
 * Additionally accepts 'bool flat' and 'url iconCheckedSource'.
 */
ButtonStyle {
	FontMetrics {
		id: fontMetrics
	}

	property int metricsUnit: metrics ? metrics.unit : fontMetrics.averageCharacterWidth

	background: Rectangle {
		anchors.fill: parent

		implicitWidth: 100
		implicitHeight: 25

		color: control.flat ? "transparent" : control.pressed ? "black" : "white"

		Image {
			anchors.fill: parent

			property int extrusion: control.flat ? 0 : metricsUnit / 4

			anchors.leftMargin: control.pressed ? 0 : extrusion
			anchors.topMargin: anchors.leftMargin
			anchors.rightMargin: control.pressed ? extrusion : 0
			anchors.bottomMargin: anchors.rightMargin

			source: control.checked ? control.iconCheckedSource : control.iconSource
			fillMode: Image.Stretch
		}
	}

	label: Item {
	}
}


================================================
FILE: assets/qml/ButtonFlat.qml
================================================
// Copyright 2015-2017 the openage authors. See copying.md for legal info.

import QtQuick 2.4
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.3

Button {
	style: ButtonFlatStyle {}
}


================================================
FILE: assets/qml/ButtonFlatStyle.qml
================================================
// Copyright 2015-2017 the openage authors. See copying.md for legal info.

import QtQuick 2.4
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.3

ButtonStyle {
	FontMetrics {
		id: fontMetrics
	}

	QtObject {
		id: d
		readonly property color color: control.hovered || control.checked ? "yellow" : "white"
	}

	background: Rectangle {
		implicitWidth: control.iconSource ? 0 : 100
		implicitHeight: control.iconSource ? 0 : 25

		color: "transparent"

		border.width:  control.text || control.hovered || !control.iconSource || control.checked ? 1 : 0
		border.color: control.checked ? "yellow" : "white"
		radius: 4
	}

	label: Item {
		implicitWidth: row.implicitWidth + (control.text ? fontMetrics.averageCharacterWidth * 2 : 0)
		implicitHeight: row.implicitHeight + (control.text ? fontMetrics.averageCharacterWidth : 0)

		Row {
			id: row
			anchors.centerIn: parent

			Image {
				sourceSize.width: control.buttonIconWidth
				sourceSize.height: control.buttonIconHeight
				source: control.iconSource
				anchors.verticalCenter: parent.verticalCenter
			}

			Text {
				id: text

				color: d.color

				text: control.text
			}
		}
	}
}


================================================
FILE: assets/qml/CheckBoxFlat.qml
================================================
// Copyright 2015-2017 the openage authors. See copying.md for legal info.

import QtQuick 2.4
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.3

CheckBox {
	style: CheckBoxFlatStyle {}
}


================================================
FILE: assets/qml/CheckBoxFlatStyle.qml
================================================
// Copyright 2015-2017 the openage authors. See copying.md for legal info.

import QtQuick 2.4
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.3

CheckBoxStyle {
	FontMetrics {
		id: fontMetrics
	}

	QtObject {
		id: metrics
		readonly property int unit: fontMetrics.averageCharacterWidth
	}

	QtObject {
		id: d
		readonly property color color: control.hovered ? "yellow" : "white"
	}

	indicator: Rectangle {
		implicitWidth: metrics.unit * 2
		implicitHeight: metrics.unit * 2

		color: "transparent"

		border.width: 1
		border.color: "white"
		radius: 4

		Rectangle {
			visible: control.checked
			color: d.color
			radius: 1
			anchors.margins: metrics.unit * .5
			anchors.fill: parent
		}
	}

	label: Text {
		color: d.color
		text: control.text
	}
}


================================================
FILE: assets/qml/CreateGameWhenReady.qml
================================================
// Copyright 2015-2017 the openage authors. See copying.md for legal info.

import QtQuick 2.4

import yay.sfttech.openage 1.0 as OA

OA.GameCreator {
	id: root

	property bool enabled: false
	property var gameControl
	property int gameControlTargetModeIndex

	property int specState: gameSpec ? gameSpec.state : OA.GameSpec.Null
	property int gameState: game ? game.state : OA.GameMain.Null

	onSpecStateChanged: {
		if (enabled && specState == OA.GameSpec.Ready)
			activate()
	}

	onGameStateChanged: {
		if (enabled && gameState == OA.GameMain.Running)
			if (gameControl.modeIndex != -1)
				gameControl.modeIndex = gameControlTargetModeIndex
			else
				console.error("CreateGameWhenReady: could not find the desired mode to switch to")
	}
}


================================================
FILE: assets/qml/GeneratorControl.qml
================================================
// Copyright 2015-2017 the openage authors. See copying.md for legal info.

import QtQuick 2.4
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1

import yay.sfttech.openage 1.0 as OA

Item {
	id: root

	property var generatorParameters
	property var gameSpec
	property var game

	implicitWidth: elements.width
	implicitHeight: elements.height

	Column {
		id: elements

		spacing: genActions.spacing

		ColumnLayout {
			id: genActions

			OA.GameSaver {
				id: gameSaver

				game: root.game
				generatorParameters: root.generatorParameters
			}

			ButtonFlat {
				Layout.fillWidth: true

				text: "save_game"
				onClicked: gameSaver.activate()
			}

			OA.GameCreator {
				id: gameCreator

				game: root.game
				gameSpec: root.gameSpec
				generatorParameters: root.generatorParameters
			}

			ButtonFlat {
				Layout.fillWidth: true

				text: "generate_game"
				onClicked: {
					gameCreator.activate()
					gameSaver.clearErrors()
				}
			}

			ButtonFlat {
				Layout.fillWidth: true

				text: "end_game"
				onClicked: {
					game.clear()
					gameCreator.clearErrors()
				}
			}

			ButtonFlat {
				Layout.fillWidth: true

				text: "reload_assets"
				onClicked: gameSpec.invalidate()
			}

			ButtonFlat {
				Layout.fillWidth: true

				text: "quit"
				onClicked: game.engine.stop()
			}
		}

		Text {
			property string errorStringSeparator: gameCreator.errorString && gameSaver.errorString ? "\n" : ""
			property string errorString: gameCreator.errorString + errorStringSeparator + gameSaver.errorString

			color: errorString ? "red" : "white"

			text: if (errorString)
					"Error: " + errorString
				else
					switch (root.game.state) {
						case OA.GameMain.Null:
							"Not running"
							break

						case OA.GameMain.Running:
							"Running"
							break

						default:
							"Unknown"
							break
					}
		}
	}
}


================================================
FILE: assets/qml/GeneratorParametersConfiguration.qml
================================================
// Copyright 2015-2017 the openage authors. See copying.md for legal info.

import QtQuick 2.4
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1

import yay.sfttech.openage 1.0 as OA

Item {
	id: root

	property var generatorParameters

	implicitHeight: parameterTable.height

	GridLayout {
		id: parameterTable

		Repeater {
			model: root.generatorParameters

			Text {
				Layout.row: index
				Layout.column: 0

				color: "white"

				text: display
			}
		}

		Repeater {
			model: root.generatorParameters

			Component {
				id: textField

				TextFieldFlat {
					property var model

					text: model.edit
					onTextChanged: model.edit = text
				}
			}

			Component {
				id: checkBox

				CheckBoxFlat {
					property var model

					checked: model.edit
					onCheckedChanged: model.edit = checked
				}
			}

			delegate: Loader {
				Layout.row: index
				Layout.column: 1

				sourceComponent: typeof(model.edit) == "boolean" ? checkBox : textField

				onLoaded: item.model = Qt.binding(function() { return model })
			}
		}
	}
}


================================================
FILE: assets/qml/IngameHud.qml
================================================
// Copyright 2015-2017 the openage authors. See copying.md for legal info.

import QtQuick 2.4
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1

import yay.sfttech.openage 1.0 as OA

Item {
	id: root

	property var actionMode
	property string playerName
	property int civIndex

	readonly property int topStripSubid: 0
	readonly property int midStripSubid: 1
	readonly property int leftRectSubid: 2
	readonly property int rightRectSubid: 3
	readonly property int resBaseSubid: 4

	readonly property string srcPrefix: "image://by-filename/converted/interface/hud"
	readonly property string pad: "0000"
	readonly property string srcSuffix: ".slp.png"
	property string hudImageSource: srcPrefix + (pad + civIndex).slice(-pad.length) + srcSuffix

	readonly property string iconsPrefix: "image://by-filename/converted/interface/"
	readonly property string iconsBorder: "image://by-filename/converted/interface/53003.slp.png.1"

	width: 1289
	height: 960

	Item {
		anchors.left: parent.left
		anchors.right: parent.right
		anchors.top: parent.top

		height: metricsUnit * 1.5 * 2.5

		Image {
			anchors.fill: parent
			source: hudImageSource + "." + root.topStripSubid

			sourceSize.height: parent.height
			fillMode: Image.Tile
		}

		RowLayout {
			anchors.fill: parent
			anchors.leftMargin: metricsUnit
			anchors.rightMargin: metricsUnit
			anchors.verticalCenter: parent.verticalCenter
			spacing: metricsUnit * 0.7

			Row {
				spacing: metricsUnit * 0.7

				Component {
					id: resourceIndicator

					Rectangle {
						property string amount
						property int iconIndex
						property bool warning

						width: metricsUnit * 1.5 * 6.5
						height: metricsUnit * 1.5 * 1.7

						color: "#7FFFFFFF"

						Rectangle {
							anchors.fill: parent
							anchors.rightMargin: metricsUnit * 0.3
							anchors.bottomMargin: metricsUnit * 0.3

							color: "black"

							Image {
								sourceSize.height: parent.height

								source: hudImageSource + "." + (root.resBaseSubid + iconIndex)
								fillMode: Image.PreserveAspectFit
							}

							Text {
								anchors.right: parent.right
								anchors.rightMargin: metricsUnit / 2
								anchors.verticalCenter: parent.verticalCenter
								text: amount

								color: "white"
							}
						}

						Rectangle {
							anchors.fill: parent
							anchors.rightMargin: metricsUnit * 0.3
							anchors.bottomMargin: metricsUnit * 0.3

							visible: warning

							color: "#80FFC100"

							SequentialAnimation on opacity {
								loops: Animation.Infinite
								PropertyAnimation { from: 0; to: 1; duration: 250 }
								PropertyAnimation { from: 1; to: 0; duration: 250 }
							}
						}
					}
				}

				Repeater {
					model: OA.Resources {
						actionMode: root.actionMode
					}

					delegate: Loader {
						sourceComponent: resourceIndicator

						onLoaded: {
							item.amount = Qt.binding(function() { return display })
							item.iconIndex = Qt.binding(function() { return index })
						}
					}
				}

				Loader {
					sourceComponent: resourceIndicator

					onLoaded: {
						item.amount = Qt.binding(function() { return root.actionMode.population })
						item.iconIndex = 4
						item.warning = Qt.binding(function() { return root.actionMode.population_warn })
					}
				}
			}

			Item {
				Layout.fillWidth: true
				Layout.minimumWidth: epoch.implicitWidth

				Rectangle {
					anchors.centerIn: parent
					width: 200
					height: metricsUnit * 2.5

					color: "black"

					Text {
						id: epoch
						anchors.centerIn: parent

						color: "white"
						text: root.playerName
					}
				}
			}

			Repeater {
				model: 5

				Rectangle {
					width: metricsUnit * 1.5 * 5
					height: metricsUnit * 1.5 * 1.5

					color: "transparent"
					border.width: 1
					border.color: "white"
				}
			}
		}
	}

	Item {
		anchors.left: parent.left
		anchors.right: parent.right
		anchors.bottom: parent.bottom

		height: metricsUnit * 1.5 * 16

		Image {
			id: leftRect

			anchors.left: parent.left
			anchors.top: parent.top
			anchors.bottom: parent.bottom

			width: height * 1.63

			source: hudImageSource + "." + root.leftRectSubid
			fillMode: Image.Stretch

			ActionsGrid {
				id: actionsGrid

				anchors.fill: parent
				anchors.topMargin: parent.height * 40 / 218
				anchors.leftMargin: parent.height * 40 / 218 + metricsUnit * 1.4
				anchors.rightMargin: parent.height * 40 / 218 + metricsUnit * 0.5
				anchors.bottomMargin: parent.height * 40 / 218 - metricsUnit * 1.4

				columns: 5
				rows: 3

				Actions {
					id: actions

					actionMode: root.actionMode
				}

				buttonActions: actions.actionObjects
			}
		}

		ColumnLayout {
			anchors.left: leftRect.right
			anchors.right: rightRect.left
			anchors.top: parent.top
			anchors.bottom: parent.bottom

			spacing: 0

			Image {
				id: borderStrip

				Layout.fillWidth: true

				sourceSize.height: metricsUnit * 1.4

				source: hudImageSource + "." + root.midStripSubid
				fillMode: Image.Tile
			}

			Rectangle {
				Layout.fillHeight: true
				Layout.fillWidth: true

				color: "#41110d"

				Paper {
					anchors.fill: parent
					tornBottom: false
				}

				Item {
					anchors.fill: parent
					id: selection_single_panel
					visible: root.actionMode.selection_size == 1

					Image {
						anchors.top: parent.top
						anchors.topMargin: metricsUnit * 2
						anchors.left: parent.left
						anchors.leftMargin: metricsUnit * 2

						width: 50
						height: 50

						id: selected_icon

						source: root.actionMode.selection_icon ? iconsPrefix + root.actionMode.selection_icon : iconsBorder
					}
					Image {
						anchors.centerIn: selected_icon

						width: 50
						height: 50

						source: iconsBorder
					}

					Text {
						anchors.top: selected_icon.top
						anchors.left: selected_icon.right
						anchors.leftMargin: metricsUnit * 1.2

						id: selected_name

						color: "black"
						text: root.actionMode.selection_name
						font.pointSize: 16
					}

					Text {
						anchors.verticalCenter: selected_name.verticalCenter
						anchors.left: selected_name.right
						anchors.leftMargin: metricsUnit * 1.2

						id: selected_type

						color: "black"
						opacity: 0.8
						text: root.actionMode.selection_type
					}

					Text {
						anchors.top: selected_name.bottom
						anchors.left: selected_name.left
						anchors.topMargin: metricsUnit

						id: selected_hp

						color: "black"
						text: root.actionMode.selection_hp
					}

					Text {
						anchors.top: selected_hp.bottom
						anchors.left: selected_icon.left
						anchors.topMargin: metricsUnit * 2

						color: "black"
						text: root.actionMode.selection_attrs
					}

					Text {
						anchors.top: parent.top
						anchors.right: parent.right
						anchors.topMargin: metricsUnit * 2
						anchors.rightMargin: metricsUnit * 2

						color: "black"
						text: root.actionMode.selection_owner
						horizontalAlignment: Text.AlignRight
					}

				}

				Item {
					anchors.fill: parent
					id: selection_group_panel
					visible: root.actionMode.selection_size > 1

					Text {
						anchors.top: parent.top
						anchors.topMargin: metricsUnit * 2
						anchors.left: parent.left
						anchors.leftMargin: metricsUnit * 2

						color: "black"
						text: root.actionMode.selection_name
						font.pointSize: 14
					}
				}

				Item {
					anchors.left: parent.left
					anchors.right: parent.right
					anchors.bottom: parent.bottom
					anchors.bottomMargin: metricsUnit * 3
					visible: actionMode.ability.length

					Text {
						anchors.centerIn: parent

						text: actionMode.ability
						font.pointSize: 14
					}
				}
			}
		}

		Image {
			id: rightRect

			anchors.right: parent.right
			anchors.top: parent.top
			anchors.bottom: parent.bottom

			width: height * 2.01

			source: hudImageSource + "." + root.rightRectSubid
			fillMode: Image.Stretch
		}
	}

	/*
	 * Metric propagation.
	 */
	FontMetrics {
		id: fontMetrics
	}

	property int metricsUnit: metrics ? metrics.unit : fontMetrics.averageCharacterWidth
}


================================================
FILE: assets/qml/Paper.qml
================================================
// Copyright 2015-2017 the openage authors. See copying.md for legal info.

import QtQuick 2.4

Item {
	id: root

	/*
	 * A paper texture.
	 */
	property url paperTextureSource: "image://by-filename/converted/interface/scr5b.slp.png.0"

	/*
	 * This texture is tiled along the item edges, bottom faces the inside.
	 * So, alpha should be zero for the pixels where to keep the paper, solid color - where it's torn off.
	 */
	property url edgeHmapSource: "image://by-filename/textures/torn_paper_edge.png.0"

	/*
	 * Which edges are torn off.
	 */
	property bool tornTop: true
	property bool tornBottom: true
	property bool tornLeft: true
	property bool tornRight: true

	/*
	 * Changing metrics.unit (currently bound to the font) scales all textures.
	 * So the details on the textures stay exactly the same relatively to metricsUnit.
	 */
	property real scaling: 8. / metricsUnit

	transform: Scale { xScale: 1. / root.scaling; yScale: 1. / root.scaling}

	Item {
		anchors.left: parent.left
		anchors.top: parent.top

		/*
		 * Do +.5 to avoid being less than parent due to truncation.
		 */
		width: (parent.width + .5) * root.scaling
		height: (parent.height + .5) * root.scaling

		Item {
			anchors.fill: parent

			/*
			 * Hack, so the child has 'visible' and 'layer.enabled'.
			 */
			clip: true

			Item {
				id: texturedPaper

				/*
				 * Hack, so that this item has 'visible' and 'layer.enabled'.
				 */
				width: parent.width
				height: parent.height
				x: parent.width

				layer.enabled: true

				Image {
					anchors.fill: parent
					source: root.paperTextureSource
					fillMode: Image.Tile

					/*
					 * Use an ellipse to darken parts that are far from the center.
					 */
					layer.enabled: true
					layer.wrapMode: ShaderEffectSource.Repeat
					layer.samplerName: "paperSource"
					layer.effect: ShaderEffect {
						fragmentShader: "
							uniform lowp sampler2D paperSource;
							varying highp vec2 qt_TexCoord0;

							const float exposure = .5;
							const float times = 3.;

							vec3 burntMidtones(vec3 src, float exposure, float times) {
								float factor = 1. + exposure * (.33);
								return pow(src.rgb, vec3(factor * times));
							}

							void main() {
								vec4 bkg = texture2D(paperSource, qt_TexCoord0);
								vec3 burnt = burntMidtones(bkg.rgb, exposure, times);

								float burnGradient = pow(pow((qt_TexCoord0.x - .5), 2.) + pow((qt_TexCoord0.y - 1.), 2.), 1.) * .9;

								gl_FragColor = vec4(mix(bkg.rgb, burnt, vec3(burnGradient)), 1.);
							}
						"
					}
				}
			}
		}

		/*
		 * Inverse QtGraphicalEffects.OpacityMask.
		 */
		Item {
			anchors.fill: parent

			layer.enabled: true

			layer.effect: ShaderEffect {
				property variant source: texturedPaper
				property variant mask: rectWithTornOffEdges

				fragmentShader: "
					uniform sampler2D source;
					uniform sampler2D mask;
					varying highp vec2 qt_TexCoord0;
					void main() {
						gl_FragColor = texture2D(source, qt_TexCoord0) * (1. - texture2D(mask, qt_TexCoord0).a);
					}
				"
			}
		}

		/*
		 * Alpha == 1.0 where the edges are torn off.
		 */
		Item {
			id: rectWithTornOffEdges

			anchors.fill: parent
			layer.enabled: true

			Image {
				anchors.left: parent.left
				anchors.right: parent.right
				anchors.top: parent.top

				source: root.edgeHmapSource
				fillMode: Image.Tile

				visible: root.tornTop
			}

			Image {
				anchors.left: parent.left
				anchors.right: parent.right
				anchors.top: parent.top

				source: root.edgeHmapSource
				fillMode: Image.Tile

				transform: Rotation {
					origin.x: rectWithTornOffEdges.width / 2
					origin.y: rectWithTornOffEdges.height / 2
					angle: 180
				}

				visible: root.tornBottom
			}

			Image {
				anchors.left: parent.left
				anchors.leftMargin: parent.height
				anchors.top: parent.top

				width: parent.height

				source: root.edgeHmapSource
				fillMode: Image.Tile

				transform: Rotation {
					origin.y: rectWithTornOffEdges.height
					angle: -90
				}

				visible: root.tornLeft
			}

			Image {
				anchors.right: parent.right
				anchors.rightMargin: parent.height
				anchors.top: parent.top

				width: parent.height

				source: root.edgeHmapSource
				fillMode: Image.Tile

				transform: Rotation {
					origin.y: rectWithTornOffEdges.height
					origin.x: rectWithTornOffEdges.height
					angle: 90
				}

				visible: root.tornRight
			}

			visible: false
		}
	}

	/*
	 * Average character width that the paper will adapt to (by scaling its texture).
	 */
	/*
	 * Metric propagation.
	 */
	FontMetrics {
		id: fontMetrics
	}

	property int metricsUnit: metrics ? metrics.unit : fontMetrics.averageCharacterWidth
}


================================================
FILE: assets/qml/TextFieldFlat.qml
================================================
// Copyright 2015-2017 the openage authors. See copying.md for legal info.

import QtQuick 2.4
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.3

TextField {
	style: TextFieldFlatStyle {}
}


================================================
FILE: assets/qml/TextFieldFlatStyle.qml
================================================
// Copyright 2015-2017 the openage authors. See copying.md for legal info.

import QtQuick 2.4
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.3

TextFieldStyle {
	textColor: "white"

	background: Rectangle {
		color: "transparent"

		border.width: 1
		border.color: "white"
		radius: 4
	}
}


================================================
FILE: assets/qml/TypePicker.qml
================================================
// Copyright 2015-2017 the openage authors. See copying.md for legal info.

import QtQuick 2.4
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1

import yay.sfttech.openage 1.0 as OA

Item {
	id: root

	// input
	property var editorMode
	property var gameSpec
	property int iconHeight

	function toggle() {
		if (!categoryPicker.current && categoryButtons.children.length)
			categoryButtons.children[0].checked = true
		else
			for (var i = 0; i < categoryButtons.children.length; ++i) {
				var item = categoryButtons.children[i]

				if (item.exclusiveGroup && item.exclusiveGroup == categoryPicker && item.checked) {
					for (var j = (i + 1) % categoryButtons.children.length; j != i; j = (j + 1) % categoryButtons.children.length) {
						var candidate = categoryButtons.children[j]

						if (candidate.exclusiveGroup && candidate.exclusiveGroup == categoryPicker) {
							candidate.checked = true
							break
						}
					}

					break
				}
			}
	}

	// output
	readonly property int current: selectedType.current ? selectedType.current.thisTypeId : -1
	property int currentHighlighted: -1

	readonly property int currentTerrain: selectedTerrain.current ? selectedTerrain.current.thisTerrainId : -1
	readonly property bool paintTerrain: categoryPicker.current && categoryPicker.current.text == "terrain"

	ColumnLayout {
		anchors.fill: parent

		Row {
			id: categoryButtons

			anchors.horizontalCenter: implicitWidth < parent.width ? parent.horizontalCenter : undefined

			ExclusiveGroup {
				id: categoryPicker
			}

			OA.Category {
				id: categoryToUse
				name: categoryPicker.current && categoryPicker.current.text != "terrain" ? categoryPicker.current.text : ""
				editorMode: root.editorMode
			}

			ButtonFlat {
				checkable: true
				exclusiveGroup: categoryPicker

				text: "terrain"
			}

			Repeater {
				model: editorMode.categories

				ButtonFlat {
					checkable: true
					exclusiveGroup: categoryPicker

					text: modelData
				}
			}
		}

		Rectangle {
			Layout.fillWidth: true
			Layout.fillHeight: true
			Layout.minimumWidth: metricsUnit * 10
			Layout.minimumHeight: metricsUnit * 10

			color: "transparent"

			border.width: 1
			border.color: "white"
			radius: 4

			Flickable {
				anchors.fill: parent
				anchors.margins: metricsUnit / 2

				boundsBehavior: Flickable.StopAtBounds

				clip: true
				contentWidth: width
				contentHeight: typeIcons.height

				Flow {
					id: typeIcons

					anchors.left: parent.left
					anchors.right: parent.right

					ExclusiveGroup {
						id: selectedType
					}

					Repeater {
						model: categoryPicker.current && categoryPicker.current.text != "terrain" ? categoryToUse : undefined

						ButtonFlat {
							checkable: true
							exclusiveGroup: selectedType

							property int thisTypeId: typeId

							property int buttonIconHeight: iconHeight
							iconSource: "image://by-graphic-id/" + display + ".0"

							onHoveredChanged: {
								if (hovered)
									root.currentHighlighted = typeId
								else if (root.currentHighlighted == typeId)
									root.currentHighlighted = -1
							}
						}
					}

					ExclusiveGroup {
						id: selectedTerrain
					}

					Repeater {
						model: categoryPicker.current && categoryPicker.current.text == "terrain" ? gameSpec.terrainIdCount : undefined

						ButtonFlat {
							checkable: true
							exclusiveGroup: selectedTerrain

							property int thisTerrainId: index

							property int buttonIconHeight: iconHeight
							iconSource: "image://by-terrain-id/" + index + ".0"
						}
					}
				}
			}
		}
	}

	/*
	 * Metric propagation.
	 */
	FontMetrics {
		id: fontMetrics
	}

	property int metricsUnit: metrics ? metrics.unit : fontMetrics.averageCharacterWidth
}


================================================
FILE: assets/qml/main.qml
================================================
// Copyright 2015-2017 the openage authors. See copying.md for legal info.

import QtQuick 2.4
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import QtQuick.Controls.Styles 1.3

import yay.sfttech.livereload 1.0
import yay.sfttech.openage 1.0 as OA

Item {
	id: root

	/*
	 * Global metric declaration.
	 */
	FontMetrics {
		id: fontMetrics
	}

	QtObject {
		id: metrics
		property real scale: 1
		property int unit: fontMetrics.averageCharacterWidth * scale
	}

	OA.GameSpec {
		id: specObj

		/**
		 * States: Null, Loading, Ready
		 */

		// Start loading assets immediately
		active: true

		assetManager: amObj

		LR.tag: "spec"
	}

	OA.LegacyAssetManager {
		id: amObj

		assetDir: OA.MainArgs.assetDir

		engine: OA.Engine

		LR.tag: "am"
	}

	OA.GameMain {
		id: gameObj

		/**
		 * States: Null, Running
		 */

		engine: OA.Engine

		LR.tag: "game"
	}

	OA.GameControl {
		id: gameControlObj

		engine: OA.Engine
		game: gameObj

		/**
		 * must be run after the engine is attached
		 */
		Component.onCompleted: {
			modes = [createModeObj, editorModeObj, actionModeObj]
			modeIndex = 0
		}

		LR.tag: "gamecontrol"
	}

	OA.GeneratorParameters {
		id: genParamsObj

		LR.tag: "gen"
	}

	ColumnLayout {
		id: controls

		anchors.left: parent.left
		anchors.right: parent.right
		anchors.top: parent.top

		spacing: fontMetrics.averageCharacterWidth * 2

		state: gameControlObj.mode ? gameControlObj.mode.name : ""

		Component {
			id: changeMode

			ButtonFlat {
				text: "change_mode"
				onClicked: gameControlObj.modeIndex = (gameControlObj.effectiveModeIndex + 1) % gameControlObj.modes.length
			}
		}

		OA.CreateMode {
			id: createModeObj
			LR.tag: "createMode"
		}

		OA.ActionMode {
			id: actionModeObj
			LR.tag: "actionMode"
		}

		OA.EditorMode {
			id: editorModeObj

			currentTypeId: typePicker.current
			currentTerrainId: typePicker.currentTerrain
			paintTerrain: typePicker.paintTerrain

			onToggle: typePicker.toggle()

			LR.tag: "editorMode"
		}

		CreateGameWhenReady {
			enabled: createWhenReady.checked

			game: gameObj
			gameSpec: specObj
			generatorParameters: genParamsObj
			gameControl: gameControlObj

			gameControlTargetModeIndex: gameControlObj.modes.indexOf(actionModeObj)
		}

		states: [
			State {
				id: creationMode
				name: createModeObj.name

				property list<Item> content: [
					Loader {
						sourceComponent: changeMode
					},
					GeneratorParametersConfiguration {
						generatorParameters: genParamsObj
					},
					GeneratorControl {
						generatorParameters: genParamsObj
						gameSpec: specObj
						game: gameObj
					},
					CheckBoxFlat {
						id: createWhenReady
						text: "create_when_ready"
						visible: specObj.state == OA.GameSpec.Loading
					}
				]

				PropertyChanges {
					target: controls
					children: creationMode.content
					anchors.topMargin: fontMetrics.averageCharacterWidth * 4
					anchors.leftMargin: fontMetrics.averageCharacterWidth * 2
				}
			},
			State {
				id: editorMode
				name: editorModeObj.name

				property list<Item> content: [
					Loader {
						sourceComponent: changeMode
					},
					TypePicker {
						id: typePicker

						Layout.preferredWidth: root.width / 4
						Layout.preferredHeight: root.height / 2

						iconHeight: fontMetrics.averageCharacterWidth * 8

						editorMode: editorModeObj
						gameSpec: specObj
					},
					Text {
						color: "white"
						text: typePicker.currentHighlighted != -1 ? typePicker.currentHighlighted : ""
					}
				]

				PropertyChanges {
					target: controls
					children: editorMode.content
					anchors.topMargin: fontMetrics.averageCharacterWidth * 4
					anchors.leftMargin: fontMetrics.averageCharacterWidth * 2
				}
			},
			State {
				id: actionMode
				name: actionModeObj.name

				property list<Item> content: [
					IngameHud {
						anchors.fill: root

						actionMode: actionModeObj
						playerName: gameControlObj.currentPlayerName
						civIndex: gameControlObj.currentCivIndex
					}
				]

				PropertyChanges {
					target: controls; children: actionMode.content
				}
			}
		]
	}

	ColumnLayout {
		anchors.left: parent.left
		anchors.right: parent.right
		anchors.top: parent.top
		anchors.topMargin: fontMetrics.averageCharacterWidth * 4
		anchors.rightMargin: fontMetrics.averageCharacterWidth * 2

		spacing: fontMetrics.averageCharacterWidth * 2

		BindsHelp {
			Layout.alignment: Qt.AlignRight

			gameControl: gameControlObj
		}
	}

	Component.onCompleted: {
		OA.ImageProviderByFilename.gameSpec = specObj
		OA.ImageProviderById.gameSpec = specObj
		OA.ImageProviderByTerrainId.gameSpec = specObj
	}
}


================================================
FILE: assets/shaders/CMakeLists.txt
================================================
install(DIRECTORY "."
	DESTINATION "${ASSET_DIR}/shaders"
	FILES_MATCHING PATTERN "*.glsl"
)


================================================
FILE: assets/shaders/alphamask.frag.glsl
================================================
// alpha masking shader
//
// applies an alpha mask texture to a base texture,
// then draws the masked texture.

// the base and mask texture, base is the plain terrain tile
uniform sampler2D base_texture;
uniform sampler2D mask_texture;

// disable blending and show the mask instead
uniform bool show_mask;

// get those interpolated texture position from vertexshader
varying vec2 base_tex_position;
varying vec2 mask_tex_position;


void main() {
	// get the texel from the uniform texture.
	vec4 base_pixel = texture2D(base_texture, base_tex_position);
	vec4 mask_pixel = texture2D(mask_texture, mask_tex_position);

	float factor = 1.0 - mask_pixel.x;

	vec4 blended_pixel = vec4(base_pixel.r, base_pixel.g, base_pixel.b, base_pixel.a - factor);

	if (show_mask) {
		gl_FragColor = mask_pixel;
	} else {
		gl_FragColor = blended_pixel;
	}
}


================================================
FILE: assets/shaders/alphamask.vert.glsl
================================================
// vertex shader for applying an alpha mask to a texture

// modelview*projection matrix
uniform mat4 mvp_matrix;

// the position of this vertex
attribute vec4 vertex_position;

// send the texture coordinates to the fragmentshader
attribute vec2 base_tex_coordinates;
attribute vec2 mask_tex_coordinates;

// send the texture coordinates to the fragmentshader
varying vec2 base_tex_position;
varying vec2 mask_tex_position;

void main(void) {
	// transform the position with the mvp matrix
	gl_Position = gl_ModelViewProjectionMatrix * vertex_position;

	// set the fixpoints for the tex coordinates at this vertex
	mask_tex_position = mask_tex_coordinates;
	base_tex_position = base_tex_coordinates;
}


================================================
FILE: assets/shaders/equalsEpsilon.glsl
================================================
bool equalsEpsilon(vec4 left, vec4 right, float epsilon) {
	return all(lessThanEqual(abs(left - right), vec4(epsilon)));
}

bool equalsEpsilon(vec3 left, vec3 right, float epsilon) {
	return all(lessThanEqual(abs(left - right), vec3(epsilon)));
}

bool equalsEpsilon(vec2 left, vec2 right, float epsilon) {
	return all(lessThanEqual(abs(left - right), vec2(epsilon)));
}

bool equalsEpsilon(float left, float right, float epsilon) {
    return (abs(left - right) <= epsilon);
}


================================================
FILE: assets/shaders/final.frag.glsl
================================================
#version 330

in vec2 tex_pos;

out vec4 out_col;

uniform sampler2D tex;

void main() {
	out_col = texture(tex, tex_pos);
}


================================================
FILE: assets/shaders/final.vert.glsl
================================================
#version 330

layout(location=0) in vec2 position;
layout(location=1) in vec2 uv;

out vec2 tex_pos;

void main() {
	gl_Position = vec4(position, 0.0, 1.0);
	tex_pos = uv;
}


================================================
FILE: assets/shaders/hud_drag_select.frag.glsl
================================================
#version 330

// Color of the drag rectangle
uniform vec4 in_col;

layout(location=0) out vec4 out_col;

void main() {
	out_col = in_col;
}


================================================
FILE: assets/shaders/hud_drag_select.vert.glsl
================================================
#version 330

layout(location=0) in vec2 position;

void main() {
	gl_Position = vec4(position, 0.0, 1.0);
}


================================================
FILE: assets/shaders/identity.vert.glsl
================================================
#version 120

// no-transformation texture mapping vertex shader

// the position of this vertex
attribute vec4 vertex_position;

// interpolated texture coordinates sent to fragment shader
varying vec2 tex_position;

void main(void) {
	gl_Position = vertex_position;

	// convert from screen coordinates (-1, 1) to texture coordinates (0, 1)
	tex_position = (vertex_position.xy + vec2(1.f)) / 2.f;
}


================================================
FILE: assets/shaders/maptexture.frag.glsl
================================================
#version 120
// total basic standard texture drawing fragment shader

// the texture data
uniform sampler2D texture;

// interpolated texture coordinates received from vertex shader
varying vec2 tex_position;

void main (void) {
	// this sets the fragment color to the corresponding texel.
	gl_FragColor = texture2D(texture, tex_position);
}


================================================
FILE: assets/shaders/maptexture.vert.glsl
================================================
//total basic standard texture mapping vertex shader

//modelview*projection matrix
uniform mat4 mvp_matrix;

//the position of this vertex
attribute vec4 vertex_position;

//the texture coordinates assigned to this vertex
attribute vec2 tex_coordinates;

//interpolated texture coordinates sent to fragment shader
varying vec2 tex_position;

void main(void) {
	//transform the vertex coordinates
	gl_Position = gl_ModelViewProjectionMatrix * vertex_position;

	//pass the fix points for texture coordinates set at this vertex
	tex_position = tex_coordinates;
}


================================================
FILE: assets/shaders/skybox.frag.glsl
================================================
#version 330

uniform vec4 in_col;

layout(location=0) out vec4 out_col;

void main() {
	out_col = in_col;
}


================================================
FILE: assets/shaders/skybox.vert.glsl
================================================
#version 330

layout(location=0) in vec2 position;

void main() {
	gl_Position = vec4(position, 0.0, 1.0);
}


================================================
FILE: assets/shaders/teamcolors.frag.glsl
================================================
//team color replacement shader
//
//looks for an alpha value specified by 'alpha_marker'
//and then replaces this pixel with the desired color,
//tinted for player_number, and using the given color as base.

//the unmodified texture itself
uniform sampler2D texture;

//the desired player number the final resulting colors
uniform int player_number;

//the alpha value which marks colors to be replaced
uniform float alpha_marker;

//color entries for all players and their subcolors
uniform vec4 player_color[NUM_OF_PLAYER_COLORS];

//interpolated texture coordinates sent from vertex shader
varying vec2 tex_position;

//create epsilon environment for float comparison
const float EPSILON = 0.001;

//do the lookup in the player color table
//for a playernumber (red, blue, etc)
//get the subcolor (brightness variations)
vec4 get_color(int playernum, int subcolor) {
	return player_color[((playernum-1) * 8) + subcolor];
}

void main() {
	//get the texel from the uniform texture.
	vec4 pixel = texture2D(texture, tex_position);

	//check if this texel has an alpha marker, so we can replace it's rgb values.
	if (player_number != 1 && equalsEpsilon(pixel[3], alpha_marker, EPSILON)) {
		//try to find the base color, there are 8 of them.
		for(int i = 0; i <= 7; i++) {
			if (equalsEpsilon(vec3(pixel), vec3(player_color[i]), EPSILON)) {
				//base color found, now replace it with the same color
				//but player_number tinted.
				gl_FragColor = get_color(player_number, i);
				return;
			}
		}

		//unknown base color gets pink muhahaha
		pixel = vec4(255.0/255.0, 20.0/255.0, 147.0/255.0, 1.0);
	}

	//else the texel had no marker so we can just draw it without player coloring
	gl_FragColor = pixel;
}


================================================
FILE: assets/shaders/terrain.frag.glsl
================================================
#version 330

in vec2 tex_pos;

layout(location=0) out vec4 out_col;

uniform sampler2D tex;

void main()
{
    vec4 tex_val = texture(tex, tex_pos);
	out_col = tex_val;
}


================================================
FILE: assets/shaders/terrain.vert.glsl
================================================
#version 330

layout (location = 0) in vec3 position;
layout (location = 1) in vec2 uv;

out vec2 tex_pos;

uniform mat4 model;

// camera parameters for transforming the object position
// and scaling the subtex to the correct size
layout (std140) uniform camera {
    // view matrix (world to view space)
    mat4  view;
    // projection matrix (view to clip space)
    mat4  proj;
    // inverse zoom factor (1.0 / zoom)
    float inv_zoom;
    // inverse viewport size (1.0 / viewport size)
    vec2  inv_viewport_size;
};

void main() {
	gl_Position = proj * view * model * vec4(position, 1.0);
    tex_pos = vec2(uv.x, 1.0 - uv.y);
}


================================================
FILE: assets/shaders/texturefont.frag.glsl
================================================
varying vec2 tex_position;
uniform sampler2D texture;
uniform vec4 color;

void main() {
	// Glyph's image data is stored in the RED channel of the texture
	float red = texture2D(texture, tex_position).r;
	if (red < 0.01) {
		discard;
	}

	gl_FragColor = color * vec4(1.0f, 1.0f, 1.0f, red);
}


================================================
FILE: assets/shaders/texturefont.vert.glsl
================================================
attribute vec4 vertex_position;
attribute vec2 tex_coordinates;
varying vec2 tex_position;

void main() {
	gl_Position = gl_ModelViewProjectionMatrix * vertex_position;
	tex_position = tex_coordinates;
}


================================================
FILE: assets/shaders/world2d.frag.glsl
================================================
#version 330

in vec2 vert_uv;

layout(location=0) out vec4 col;
layout(location=1) out uint id;

uniform sampler2D tex;
uniform uint u_id;

// position (top left corner) and size: (x, y, width, height)
uniform vec4 tile_params;

vec2 uv = vec2(
	vert_uv.x * tile_params.z + tile_params.x,
	vert_uv.y * tile_params.w + tile_params.y
);

void main() {
	vec4 tex_val = texture(tex, uv);
	int alpha = int(round(tex_val.a * 255));
	switch (alpha) {
		case 0:
			col = tex_val;
			discard;

			// do not save the ID
			return;
		case 254:
			col = vec4(1.0f, 0.0f, 0.0f, 1.0f);
			break;
		case 252:
			col = vec4(0.0f, 1.0f, 0.0f, 1.0f);
			break;
		case 250:
			col = vec4(0.0f, 0.0f, 1.0f, 1.0f);
			break;
		default:
			col = tex_val;
			break;
	}
	id = u_id;
}


================================================
FILE: assets/shaders/world2d.vert.glsl
================================================
#version 330

layout(location=0) in vec2 v_position;
layout(location=1) in vec2 uv;

out vec2 vert_uv;

// camera parameters for transforming the object position
// and scaling the subtex to the correct size
layout (std140) uniform camera {
    // view matrix (world to view space)
    mat4  view;
    // projection matrix (view to clip space)
    mat4  proj;
    // inverse zoom factor (1.0 / zoom)
    // high zoom = upscale subtex
    // low zoom = downscale subtex
    float inv_zoom;
    // inverse viewport size (1.0 / viewport size)
    vec2  inv_viewport_size;
};

// can be used to move the object position in world space _before_
// it's transformed to clip space
// this is usually unnecessary because we want to draw the
// subtex where the object is, so this can be set to the identity matrix
uniform mat4 model;

// position of the object in world space
uniform vec3 obj_world_position;

// flip the subtexture horizontally/vertically
uniform bool flip_x;
uniform bool flip_y;

// parameters for scaling and moving the subtex
// to the correct position in clip space

// animation scalefactor
// scales the vertex positions so that they
// match the subtex dimensions
//
// high animation scale = downscale subtex
// low animation scale = upscale subtex
uniform float scale;

// size of the subtex (in pixels)
uniform vec2 subtex_size;

// offset of the subtex anchor point
// from the subtex center (in pixels)
// used to move the subtex so that the anchor point
// is at the object position
uniform vec2 anchor_offset;

void main() {
    // translate the position of the object from world space to clip space
    // this is the position where we want to draw the subtex in 2D
	vec4 obj_clip_pos = proj * view * model * vec4(obj_world_position, 1.0);

    // subtex has to be scaled to account for the zoom factor
    // and the animation scale factor. essentially this is (animation scale / zoom).
    float zoom_scale = scale * inv_zoom;

    // Scale the subtex vertices
    // we have to account for the viewport size to get the correct dimensions
    // and then scale the subtex to the zoom factor to get the correct size
    vec2 vert_scale = zoom_scale * subtex_size * inv_viewport_size;

    // Scale the anchor offset with the same method as above
    // to get the correct anchor position in the viewport
    vec2 anchor_scale = zoom_scale * anchor_offset * inv_viewport_size;

    // if the subtex is flipped, we also need to flip the anchor offset
    // essentially, we invert the coordinates for the flipped axis
    float anchor_x = float(flip_x) * -1.0 * anchor_scale.x + float(!flip_x) * anchor_scale.x;
    float anchor_y = float(flip_y) * -1.0 * anchor_scale.y + float(!flip_y) * anchor_scale.y;

    // offset the clip position by the offset of the subtex anchor
    // imagine this as pinning the subtex to the object position at the subtex anchor point
    obj_clip_pos += vec4(anchor_x, anchor_y, 0.0, 0.0);

    // create a move matrix for positioning the vertices
    // uses the vert scale and the transformed object position in clip space
    mat4 move = mat4(vert_scale.x,   0.0,            0.0,            0.0,
                     0.0,            vert_scale.y,   0.0,            0.0,
                     0.0,            0.0,            1.0,            0.0,
                     obj_clip_pos.x, obj_clip_pos.y, obj_clip_pos.z, 1.0);

    // calculate the final vertex position
    gl_Position = move * vec4(v_position, 0.0, 1.0);

    // if the subtex is flipped, we also need to flip the uv tex coordinates
    // essentially, we invert the coordinates for the flipped axis

    // !flip_x is default because OpenGL uses bottom-left as its origin
    float uv_x = float(!flip_x) * uv.x + float(flip_x) * (1.0 - uv.x);
    float uv_y = float(flip_y) * uv.y + float(!flip_y) * (1.0 - uv.y);

    vert_uv = vec2(uv_x, uv_y);
}


================================================
FILE: assets/shaders/world3d.vert.glsl
================================================
#version 330

layout(location=0) in vec2 position;
layout(location=1) in vec2 uv;

out vec2 vert_uv;

uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;

void main() {
	gl_Position = proj * view * model * vec4(position, 0.0, 1.0);
    vert_uv = vec2(uv.x, 1.0 - uv.y);
}


================================================
FILE: assets/test/CMakeLists.txt
================================================
# Copyright 2023-2023 the openage authors. See copying.md for legal info.

add_subdirectory(nyan/)
add_subdirectory(qml/)
add_subdirectory(shaders/)
add_subdirectory(textures/)


================================================
FILE: assets/test/nyan/CMakeLists.txt
================================================
install(DIRECTORY "."
	DESTINATION "${ASSET_DIR}/test/nyan"
	FILES_MATCHING PATTERN "*.nyan"
)


================================================
FILE: assets/test/nyan/pong.nyan
================================================
!version 1

PongGame():
    ball : Ball
    player1 : Player
    player2 : Player

Ball():
    Color():
        r : int = 0
        g : int = 200
        b : int = 0
    color : Color = Color

Player():
    lives : int = 3
    size : int = 200

GameTest(PongGame):
    ball = Ball
    player1 = Player
    player2 = Player

LeftColor<Ball.Color>():
    r = 0
    g = 20
    b = 230

RightColor<Ball.Color>():
    r = 180
    g = 40
    b = 0


================================================
FILE: assets/test/qml/CMakeLists.txt
================================================
install(DIRECTORY "."
	DESTINATION "${ASSET_DIR}/test/qml"
	FILES_MATCHING PATTERN "*.qml"
)


================================================
FILE: assets/test/qml/main.qml
================================================
// Copyright 2015-2017 the openage authors. See copying.md for legal info.

import QtQuick 2.4
import yay.sfttech.livereload 1.0
import yay.sfttech.openage 1.0 as OA

Item {
	id: root

	Rectangle {
		width: 200
		height: 200
		color: "red"

		Rectangle {
			x: 100
			y: 100
			width: 100
			height: 100
			color: "blue"

			Rectangle {
				id: r
				width: 50
				height: 50
				color: "green"
			}
		}

		MouseArea {
			anchors.fill: parent
			onClicked: r.color = "yellow"
		}
	}
}


================================================
FILE: assets/test/shaders/CMakeLists.txt
================================================
install(DIRECTORY "."
	DESTINATION "${ASSET_DIR}/test/shaders"
	FILES_MATCHING PATTERN "*.glsl"
)


================================================
FILE: assets/test/shaders/demo_0_display.frag.glsl
================================================
#version 330

out vec4 col;

void main() {
    col = vec4(1.0, 0.4, 0.0, 0.8);
}


================================================
FILE: assets/test/shaders/demo_0_display.vert.glsl
================================================
#version 330

layout(location=0) in vec2 position;

void main() {
	gl_Position = vec4(position, 0.0, 1.0);
}


================================================
FILE: assets/test/shaders/demo_1_display.frag.glsl
================================================
#version 330

uniform sampler2D color_texture;

in vec2 v_uv;
out vec4 col;

void main() {
	col = texture(color_texture, v_uv);
}


================================================
FILE: assets/test/shaders/demo_1_display.vert.glsl
================================================
#version 330

layout(location=0) in vec2 position;
layout(location=1) in vec2 uv;
out vec2 v_uv;

void main() {
	gl_Position =  vec4(position, 0.0, 1.0);
	v_uv = uv;
}


================================================
FILE: assets/test/shaders/demo_1_obj.frag.glsl
================================================
#version 330

in vec2 v_uv;
uniform sampler2D tex;
uniform uint u_id;

layout(location=0) out vec4 col;
layout(location=1) out uint id;

void main() {
	vec4 tex_val = texture(tex, v_uv);
	if (tex_val.a == 0) {
		discard;
	}
	col = tex_val;
	id = u_id;
}


================================================
FILE: assets/test/shaders/demo_1_obj.vert.glsl
================================================
#version 330

layout(location=0) in vec2 position;
layout(location=1) in vec2 uv;
uniform mat4 mv;
uniform mat4 proj;
out vec2 v_uv;

void main() {
	gl_Position = proj * mv * vec4(position, 0.0, 1.0);
	v_uv = vec2(uv.x, 1.0 - uv.y);
}


================================================
FILE: assets/test/shaders/demo_2_display.frag.glsl
================================================
#version 330

uniform sampler2D color_texture;

in vec2 v_uv;
out vec4 col;

void main() {
	col = texture(color_texture, v_uv);
}


================================================
FILE: assets/test/shaders/demo_2_display.vert.glsl
================================================
#version 330

layout(location=0) in vec2 position;
layout(location=1) in vec2 uv;
out vec2 v_uv;

void main() {
	gl_Position = vec4(position, 0.0, 1.0);
	v_uv = uv;
}


================================================
FILE: assets/test/shaders/demo_2_obj.frag.glsl
================================================
#version 330

in vec2 v_uv;
uniform sampler2D tex;
uniform uint u_id;

layout(location=0) out vec4 col;
layout(location=1) out uint id;

void main() {
	vec4 tex_val = texture(tex, v_uv);
	int alpha = int(round(tex_val.a * 255));
	switch (alpha) {
		case 0:
		discard;
		break;
		case 254:
		col = vec4(1.0f, 0.0f, 0.0f, 1.0f);
		break;
		case 252:
		col = vec4(0.0f, 1.0f, 0.0f, 1.0f);
		break;
		case 250:
		col = vec4(0.0f, 0.0f, 1.0f, 1.0f);
		break;
		default:
	    col = tex_val;
		break;
	}
	id = u_id;
}


================================================
FILE: assets/test/shaders/demo_2_obj.vert.glsl
================================================
#version 330

layout(location=0) in vec2 position;
layout(location=1) in vec2 uv;

uniform mat4 mv;
uniform mat4 proj;
uniform vec4 offset_tile;

float width = offset_tile.y - offset_tile.x;
float height = offset_tile.w - offset_tile.z;

out vec2 v_uv;

void main() {
	gl_Position = proj * mv * vec4(position, 0.0, 1.0);
    v_uv = vec2((uv.x * width) + offset_tile.x, (((1.0 - uv.y) * height) + offset_tile.z));
}


================================================
FILE: assets/test/shaders/demo_4_display.frag.glsl
================================================
#version 330

uniform sampler2D color_texture;

in vec2 v_uv;
out vec4 col;

void main() {
	col = texture(color_texture, v_uv);
}


================================================
FILE: assets/test/shaders/demo_4_display.vert.glsl
================================================
#version 330

layout(location=0) in vec2 position;
layout(location=1) in vec2 uv;
out vec2 v_uv;

void main() {
	gl_Position = vec4(position, 0.0, 1.0);
	v_uv = uv;
}


================================================
FILE: assets/test/shaders/demo_4_obj.frag.glsl
================================================
#version 330

in vec2 v_uv;
uniform sampler2D tex;
uniform uint u_id;

layout(location=0) out vec4 col;
layout(location=1) out uint id;

void main() {
	vec4 tex_val = texture(tex, v_uv);
	int alpha = int(round(tex_val.a * 255));
	switch (alpha) {
		case 0:
		discard;
		break;
		case 254:
		col = vec4(1.0f, 0.0f, 0.0f, 1.0f);
		break;
		case 252:
		col = vec4(0.0f, 1.0f, 0.0f, 1.0f);
		break;
		case 250:
		col = vec4(0.0f, 0.0f, 1.0f, 1.0f);
		break;
		default:
	    col = tex_val;
		break;
	}
	id = u_id;
}


================================================
FILE: assets/test/shaders/demo_4_obj.vert.glsl
================================================
#version 330

layout(location=0) in vec2 position;
layout(location=1) in vec2 uv;

uniform mat4 mv;
uniform mat4 proj;
uniform vec4 offset_tile;

float width = offset_tile.y - offset_tile.x;
float height = offset_tile.w - offset_tile.z;

out vec2 v_uv;

void main() {
	gl_Position = proj * mv * vec4(position, 0.0, 1.0);
    v_uv = vec2((uv.x * width) + offset_tile.x, (((1.0 - uv.y) * height) + offset_tile.z));
}


================================================
FILE: assets/test/shaders/demo_5_obj.frag.glsl
================================================
#version 330

in vec2 tex_pos;

layout(location=0) out vec4 out_col;

uniform sampler2D tex;

void main()
{
    vec4 tex_val = texture(tex, tex_pos);
	out_col = tex_val;
}


================================================
FILE: assets/test/shaders/demo_5_obj.vert.glsl
================================================
#version 330

layout (location = 0) in vec3 position;
layout (location = 1) in vec2 uv;

out vec2 tex_pos;

uniform mat4 model;

layout (std140) uniform cam {
    mat4 view;
    mat4 proj;
};

void main() {
	gl_Position = proj * view * model * vec4(position, 1.0);
    tex_pos = vec2(uv.x, 1.0 - uv.y);
}


================================================
FILE: assets/test/shaders/demo_6_2d.frag.glsl
================================================
#version 330

in vec2 vert_uv;

layout(location=0) out vec4 col;

uniform sampler2D tex;

// position (top left corner) and size: (x, y, width, height)
uniform vec4 tile_params;

vec2 uv = vec2(
	vert_uv.x * tile_params.z + tile_params.x,
	vert_uv.y * tile_params.w + tile_params.y
);

void main() {
	vec4 tex_val = texture(tex, uv);
	int alpha = int(round(tex_val.a * 255));
	switch (alpha) {
		case 0:
			col = tex_val;
			discard;
		case 254:
			col = vec4(1.0f, 0.0f, 0.0f, 1.0f);
			break;
		case 252:
			col = vec4(0.0f, 1.0f, 0.0f, 1.0f);
			break;
		case 250:
			col = vec4(0.0f, 0.0f, 1.0f, 1.0f);
			break;
		default:
			col = tex_val;
			break;
	}
}


================================================
FILE: assets/test/shaders/demo_6_2d.vert.glsl
================================================
#version 330

layout(location=0) in vec2 v_position;
layout(location=1) in vec2 uv;

out vec2 vert_uv;

// camera parameters for transforming the object position
// and scaling the subtex to the correct size
layout (std140) uniform camera {
    // view matrix (world to view space)
    mat4  view;
    // projection matrix (view to clip space)
    mat4  proj;
    // inverse zoom factor (1.0 / zoom)
    // high zoom = upscale subtex
    // low zoom = downscale subtex
    float inv_zoom;
    // inverse viewport size (1.0 / viewport size)
    vec2  inv_viewport_size;
};

// position of the object in world space
uniform vec3 obj_world_position;

// parameters for scaling and moving the subtex
// to the correct position in clip space

// animation scalefactor
// scales the vertex positions so that they
// match the subtex dimensions
//
// high animation scale = downscale subtex
// low animation scale = upscale subtex
uniform float scale;

// size of the subtex (in pixels)
uniform vec2 subtex_size;

// offset of the subtex anchor point
// from the subtex center (in pixels)
// used to move the subtex so that the anchor point
// is at the object position
uniform vec2 anchor_offset;

void main() {
    // translate the position of the object from world space to clip space
    // this is the position where we want to draw the subtex in 2D
	vec4 obj_clip_pos = proj * view * vec4(obj_world_position, 1.0);

    // subtex has to be scaled to account for the zoom factor
    // and the animation scale factor. essentially this is (animation scale / zoom).
    float zoom_scale = scale * inv_zoom;

    // Scale the subtex vertices
    // we have to account for the viewport size to get the correct dimensions
    // and then scale the subtex to the zoom factor to get the correct size
    vec2 vert_scale = zoom_scale * subtex_size * inv_viewport_size;

    // Scale the anchor offset with the same method as above
    // to get the correct anchor position in the viewport
    vec2 anchor_scale = zoom_scale * anchor_offset * inv_viewport_size;

    // offset the clip position by the offset of the subtex anchor
    // imagine this as pinning the subtex to the object position at the subtex anchor point
    obj_clip_pos += vec4(anchor_scale.x, anchor_scale.y, 0.0, 0.0);

    // create a move matrix for positioning the vertices
    // uses the vert scale and the transformed object position in clip space
    mat4 move = mat4(vert_scale.x,   0.0,            0.0,            0.0,
                     0.0,            vert_scale.y,   0.0,            0.0,
                     0.0,            0.0,            1.0,            0.0,
                     obj_clip_pos.x, obj_clip_pos.y, obj_clip_pos.z, 1.0);

    // calculate the final vertex position
    gl_Position = move * vec4(v_position, 0.0, 1.0);

    // flip y axis because OpenGL uses bottom-left as its origin
    float uv_x = uv.x;
    float uv_y = 1.0 - uv.y;

    vert_uv = vec2(uv_x, uv_y);
}


================================================
FILE: assets/test/shaders/demo_6_2d_frame.frag.glsl
================================================
#version 330

out vec4 outcol;

uniform vec4 incol;

void main() {
    outcol = incol;
}


================================================
FILE: assets/test/shaders/demo_6_2d_frame.vert.glsl
================================================
#version 330

layout(location=0) in vec2 v_position;

// camera parameters for transforming the object position
// and scaling the subtex to the correct size
layout (std140) uniform camera {
    // view matrix (world to view space)
    mat4  view;
    // projection matrix (view to clip space)
    mat4  proj;
    // inverse zoom factor (1.0 / zoom)
    float inv_zoom;
    // inverse viewport size (1.0 / viewport size)
    vec2  inv_viewport_size;
};

// position of the object in world space
uniform vec3 obj_world_position;

// parameters for scaling and moving the subtex
// to the correct position in clip space

// animation scalefactor
// scales the vertex positions so that they
// match the subtex dimensions
//
// high animation scale = downscale subtex
// low animation scale = upscale subtex
uniform float scale;

// size of the frame (in pixels)
uniform vec2 frame_size;

void main() {
    // translate the position of the object from world space to clip space
    // this is the position where we want to draw the subtex in 2D
	vec4 obj_clip_pos = proj * view * vec4(obj_world_position, 1.0);

    // subtex has to be scaled to account for the zoom factor
    // and the animation scale factor. essentially this is (animation scale / zoom).
    float zoom_scale = scale * inv_zoom;

    // Scale the subtex vertices
    // we have to account for the viewport size to get the correct dimensions
    // and then scale the frame to the zoom factor to get the correct size
    vec2 vert_scale = zoom_scale * frame_size * inv_viewport_size;

    // create a move matrix for positioning the vertices
    // uses the vert scale and the transformed object position in clip space
    mat4 move = mat4(vert_scale.x,   0.0,            0.0,            0.0,
                     0.0,            vert_scale.y,   0.0,            0.0,
                     0.0,            0.0,            1.0,            0.0,
                     obj_clip_pos.x, obj_clip_pos.y, obj_clip_pos.z, 1.0);

    // calculate the final vertex position
    gl_Position = move * vec4(v_position, 0.0, 1.0);
}


================================================
FILE: assets/test/shaders/demo_6_2d_frustum_frame.vert.glsl
================================================
#version 330

layout(location=0) in vec2 v_position;

void main() {
    // flip the y coordinate in OpenGL
    gl_Position = vec4(v_position.x, v_position.y, 0.0, 1.0);
}


================================================
FILE: assets/test/shaders/demo_6_3d.frag.glsl
================================================
#version 330

in vec2 tex_pos;

layout(location=0) out vec4 out_col;

uniform sampler2D tex;

void main()
{
    vec4 tex_val = texture(tex, tex_pos);
	out_col = tex_val;
}


================================================
FILE: assets/test/shaders/demo_6_3d.vert.glsl
================================================
#version 330

layout (location = 0) in vec3 position;
layout (location = 1) in vec2 uv;

out vec2 tex_pos;

// camera parameters for transforming the object position
// and scaling the subtex to the correct size
layout (std140) uniform camera {
    // view matrix (world to view space)
    mat4  view;
    // projection matrix (view to clip space)
    mat4  proj;
    // inverse zoom factor (1.0 / zoom)
    float inv_zoom;
    // inverse viewport size (1.0 / viewport size)
    vec2  inv_viewport_size;
};

void main() {
	gl_Position = proj * view * vec4(position, 1.0);
    tex_pos = vec2(uv.x, 1.0 - uv.y);
}


================================================
FILE: assets/test/shaders/demo_6_display.frag.glsl
================================================
#version 330

uniform sampler2D color_texture;

in vec2 v_uv;
out vec4 col;

void main() {
	col = texture(color_texture, v_uv);
}


================================================
FILE: assets/test/shaders/demo_6_display.vert.glsl
================================================
#version 330

layout(location=0) in vec2 position;
layout(location=1) in vec2 uv;
out vec2 v_uv;

void main() {
	gl_Position = vec4(position, 0.0, 1.0);
	v_uv = uv;
}


================================================
FILE: assets/test/shaders/demo_7_shader_command.frag.glsl
================================================
#version 330

in vec2 tex_coord;
out vec4 frag_color;

uniform float time;

void main() {
	// PLACEHOLDER: color
	// PLACEHOLDER: alpha
	frag_color = vec4(r, g, b, alpha);
}


================================================
FILE: assets/test/shaders/demo_7_shader_command.vert.glsl
================================================
#version 330

in vec2 position;
out vec2 tex_coord;

void main() {
	tex_coord = position.xy * 0.5 + 0.5;
	gl_Position = vec4(position.xy, 0.0, 1.0);
}


================================================
FILE: assets/test/shaders/demo_7_snippets/alpha.snippet
================================================
float alpha = (sin(time) + 1.0) * 0.5;


================================================
FILE: assets/test/shaders/demo_7_snippets/color.snippet
================================================
float r = 0.5 + 0.5 * sin(time);
float g = 0.5 + 0.5 * sin(time + 2.0);
float b = 0.5 + 0.5 * sin(time + 4.0);


================================================
FILE: assets/test/shaders/pathfinding/CMakeLists.txt
================================================
install(DIRECTORY "."
	DESTINATION "${ASSET_DIR}/test/shaders/pathfinding"
	FILES_MATCHING PATTERN "*.glsl"
)


================================================
FILE: assets/test/shaders/pathfinding/demo_0_cost_field.frag.glsl
================================================
#version 330

in float v_cost;

out vec4 out_col;

void main()
{
    if (v_cost == 255.0) {
        out_col = vec4(0.0, 0.0, 0.0, 1.0);
        return;
    }
    float cost = (v_cost / 256) * 2.0;
    float red = clamp(cost, 0.0, 1.0);
    float green = clamp(2.0 - cost, 0.0, 1.0);
	out_col = vec4(red, green, 0.0, 1.0);
}


================================================
FILE: assets/test/shaders/pathfinding/demo_0_cost_field.vert.glsl
================================================
#version 330

layout (location = 0) in vec3 position;
layout (location = 1) in float cost;

uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;

out float v_cost;

void main() {
	gl_Position = proj * view * model * vec4(position, 1.0);
    v_cost = cost;
}


================================================
FILE: assets/test/shaders/pathfinding/demo_0_display.frag.glsl
================================================
#version 330

uniform sampler2D color_texture;

in vec2 v_uv;
out vec4 col;

void main() {
	col = texture(color_texture, v_uv);
}


================================================
FILE: assets/test/shaders/pathfinding/demo_0_display.vert.glsl
================================================
#version 330

layout(location=0) in vec2 position;
layout(location=1) in vec2 uv;
out vec2 v_uv;

void main() {
	gl_Position =  vec4(position, 0.0, 1.0);
	v_uv = uv;
}


================================================
FILE: assets/test/shaders/pathfinding/demo_0_flow_field.frag.glsl
================================================
#version 330

/// Flow field value
in float flow_val;

/// Integration field flags
in float int_val;

out vec4 outcol;

int WAVEFRONT_BLOCKED = 0x04;
int LINE_OF_SIGHT = 0x20;
int PATHABLE = 0x10;

void main() {
    int flow_flags = int(flow_val) & 0xF0;
    int int_flags = int(int_val);
    if (bool(int_flags & WAVEFRONT_BLOCKED)) {
        // wavefront blocked
        outcol = vec4(0.9, 0.9, 0.9, 1.0);
        return;
    }

    if (bool(int_flags & LINE_OF_SIGHT)) {
        // line of sight
        outcol = vec4(1.0, 1.0, 1.0, 1.0);
        return;
    }

    if (bool(flow_flags & PATHABLE)) {
        // pathable
        outcol = vec4(0.7, 0.7, 0.7, 1.0);
        return;
    }

    // not pathable
    outcol = vec4(0.0, 0.0, 0.0, 1.0);
}


================================================
FILE: assets/test/shaders/pathfinding/demo_0_flow_field.vert.glsl
================================================
#version 330

layout(location=0) in vec3 position;
layout(location=1) in float flow_cell;
layout(location=2) in float int_cell;

uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;

out float flow_val;
out float int_val;

void main() {
	gl_Position = proj * view * model * vec4(position, 1.0);
    flow_val = flow_cell;
    int_val = int_cell;
}


================================================
FILE: assets/test/shaders/pathfinding/demo_0_grid.frag.glsl
================================================
#version 330

out vec4 out_col;

void main()
{
	out_col = vec4(0.0, 0.0, 0.0, 0.3);
}


================================================
FILE: assets/test/shaders/pathfinding/demo_0_grid.vert.glsl
================================================
#version 330

layout (location = 0) in vec3 position;

uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;

void main() {
	gl_Position = proj * view * model * vec4(position, 1.0);
}


================================================
FILE: assets/test/shaders/pathfinding/demo_0_integration_field.frag.glsl
================================================
#version 330

in float v_cost;

out vec4 out_col;

void main()
{
    if (v_cost > 512.0) {
        out_col = vec4(0.0, 0.0, 0.0, 1.0);
        return;
    }
    float cost = 0.05 * v_cost;
    float green = clamp(1.0 - cost, 0.0, 1.0);
	out_col = vec4(0.75, green, 0.5, 1.0);
}


================================================
FILE: assets/test/shaders/pathfinding/demo_0_integration_field.vert.glsl
================================================
#version 330

layout (location = 0) in vec3 position;
layout (location = 1) in float cost;

uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;

out float v_cost;

void main() {
	gl_Position = proj * view * model * vec4(position, 1.0);
    v_cost = cost;
}


================================================
FILE: assets/test/shaders/pathfinding/demo_0_obj.frag.glsl
================================================
#version 330

uniform vec4 color;

out vec4 outcol;

void main() {
    outcol = color;
}


================================================
FILE: assets/test/shaders/pathfinding/demo_0_obj.vert.glsl
================================================
#version 330

layout(location=0) in vec2 position;

void main() {
	gl_Position = vec4(position, 0.0, 1.0);
}


================================================
FILE: assets/test/shaders/pathfinding/demo_0_vector.frag.glsl
================================================
#version 330

uniform vec4 color;

out vec4 outcol;

void main() {
    outcol = color;
}


================================================
FILE: assets/test/shaders/pathfinding/demo_0_vector.vert.glsl
================================================
#version 330

layout(location=0) in vec3 position;

uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;

void main() {
	gl_Position = proj * view * model * vec4(position, 1.0);
}


================================================
FILE: assets/test/shaders/pathfinding/demo_1_display.frag.glsl
================================================
#version 330

uniform sampler2D color_texture;

in vec2 v_uv;
out vec4 col;

void main() {
	col = texture(color_texture, v_uv);
}


================================================
FILE: assets/test/shaders/pathfinding/demo_1_display.vert.glsl
================================================
#version 330

layout(location=0) in vec2 position;
layout(location=1) in vec2 uv;
out vec2 v_uv;

void main() {
	gl_Position =  vec4(position, 0.0, 1.0);
	v_uv = uv;
}


================================================
FILE: assets/test/shaders/pathfinding/demo_1_grid.frag.glsl
================================================
#version 330

out vec4 out_col;

void main()
{
	out_col = vec4(0.0, 0.0, 0.0, 0.3);
}


================================================
FILE: assets/test/shaders/pathfinding/demo_1_grid.vert.glsl
================================================
#version 330

layout (location = 0) in vec2 position;

uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;

void main() {
	gl_Position = proj * view * model * vec4(position, 0.0, 1.0);
}


================================================
FILE: assets/test/shaders/pathfinding/demo_1_obj.frag.glsl
================================================
#version 330

uniform vec4 color;

out vec4 outcol;

void main() {
    outcol = color;
}


================================================
FILE: assets/test/shaders/pathfinding/demo_1_obj.vert.glsl
================================================
#version 330

layout(location=0) in vec2 position;

uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;

void main() {
	gl_Position = proj * view * model * vec4(position, 0.0, 1.0);
}


================================================
FILE: assets/test/textures/CMakeLists.txt
================================================
install(DIRECTORY "."
	DESTINATION "${ASSET_DIR}/test/textures"
	PATTERN "CMakeLists.txt" EXCLUDE
)


================================================
FILE: assets/test/textures/test_animation.sprite
================================================
# Copyright 2021-2021 the openage authors. See copying.md for legal info.
# openage sprite definition file

version 2

texture 0 "test_texture.texture"

scalefactor 1.0

layer 0 mode=loop position=20 time_per_frame=0.125

angle 0

frame 0 0 0 0 0
frame 1 0 0 0 1
frame 2 0 0 0 2
frame 3 0 0 0 3
frame 4 0 0 0 4
frame 5 0 0 0 5
frame 6 0 0 0 6
frame 7 0 0 0 7
frame 8 0 0 0 8
frame 9 0 0 0 9
frame 10 0 0 0 10
frame 11 0 0 0 11
frame 12 0 0 0 12
frame 13 0 0 0 13
frame 14 0 0 0 14
frame 15 0 0 0 15
frame 16 0 0 0 16
frame 17 0 0 0 17


================================================
FILE: assets/test/textures/test_gaben.sprite
================================================
# Copyright 2023-2023 the openage authors. See copying.md for legal info.
# openage sprite definition file

version 2

texture 0 "test_gaben.texture"

scalefactor 0.2

layer 0 mode=once

angle 0

frame 0 0 0 0 0


================================================
FILE: assets/test/textures/test_gaben.texture
================================================
# Copyright 2023-2023 the openage authors.
# openage texture definition file

version 1

imagefile "gaben.png"

size 719 1073

pxformat rgba8 cbits=True

subtex 0 0 719 1073 359 1000


================================================
FILE: assets/test/textures/test_missing.sprite
================================================
# Copyright 2023-2023 the openage authors. See copying.md for legal info.
# openage sprite definition file

version 2

texture 0 "test_missing.texture"

scalefactor 1.0

layer 0 mode=once

angle 0

frame 0 0 0 0 0


================================================
FILE: assets/test/textures/test_missing.texture
================================================
# Copyright 2023-2023 the openage authors.
# openage texture definition file

version 1

imagefile "missing.png"

size 32 32

pxformat rgba8 cbits=True

subtex 0 0 32 32 16 16


================================================
FILE: assets/test/textures/test_tank.sprite
================================================
# Copyright 2023-2023 the openage authors. See copying.md for legal info.
# openage sprite definition file

version 2

texture 0 "test_tank.texture"

scalefactor 2.0

layer 0 mode=off

angle 0
angle 45
angle 90
angle 135
angle 180
angle 225
angle 270
angle 315

frame 0 0 0 0 0
frame 0 45 0 0 1
frame 0 90 0 0 2
frame 0 135 0 0 3
frame 0 180 0 0 4
frame 0 225 0 0 5
frame 0 270 0 0 6
frame 0 315 0 0 7


================================================
FILE: assets/test/textures/test_tank.texture
================================================
# The image file was adapted from the "German WW2 isometric pixel tanks" sprite pack,
# Copyright 2020-2020 by jh2assets.
#
# It's licensed under the terms of the Creative Commons Attribution v4.0 International license.
# (https://creativecommons.org/licenses/by/4.0/)
#
# The original version can be found at:
# https://jimhatama.itch.io/german-ww2-pixel-tanks
#
# Modifications by us:
#   - Merged sprites from the "german_panzer4" animation into one spritesheet
#
# Copyright 2023-2023 the openage authors.
# openage texture definition file

version 1

imagefile "test_tank.png"

size 153 178

pxformat rgba8 cbits=False

subtex 109 101 32 45 16 22
subtex 81 55 68 44 34 22
subtex 1 40 78 37 39 18
subtex 82 1 70 52 35 26
subtex 73 101 34 54 17 27
subtex 1 79 70 51 35 25
subtex 1 1 79 37 38 18
subtex 1 132 68 45 34 22


================================================
FILE: assets/test/textures/test_tank_mirrored.sprite
================================================
# Copyright 2023-2023 the openage authors. See copying.md for legal info.
# openage sprite definition file

version 2

texture 0 "test_tank.texture"

scalefactor 2.0

layer 0 mode=off

angle 0
angle 45
angle 90
angle 135
angle 180
angle 225 mirror_from=135
angle 270 mirror_from=90
angle 315 mirror_from=45

frame 0 0 0 0 0
frame 0 45 0 0 1
frame 0 90 0 0 2
frame 0 135 0 0 3
frame 0 180 0 0 4


================================================
FILE: assets/test/textures/test_terrain.terrain
================================================
# Copyright 2023-2023 the openage authors. See copying.md for legal info.
# openage terrain definition file

version 2

texture 0 "test_terrain.texture"

scalefactor 1.0

layer 0

frame 0 0 0 0


================================================
FILE: assets/test/textures/test_terrain.texture
================================================
# Copyright 2023-2023 the openage authors.
# openage texture definition file

version 1

imagefile "test_terrain.png"

size 500 500

pxformat rgba8 cbits=True

subtex 0 0 500 500 0 0


================================================
FILE: assets/test/textures/test_terrain2.terrain
================================================
# Copyright 2023-2023 the openage authors. See copying.md for legal info.
# openage terrain definition file

version 2

texture 0 "test_terrain2.texture"

scalefactor 1.0

layer 0

frame 0 0 0 0


================================================
FILE: assets/test/textures/test_terrain2.texture
================================================
# Copyright 2023-2023 the openage authors.
# openage texture definition file

version 1

imagefile "test_terrain2.png"

size 500 500

pxformat rgba8 cbits=True

subtex 0 0 500 500 0 0


================================================
FILE: assets/test/textures/test_texture.texture
================================================
# The image file was adapted from the "Elemental Ground Monk" sprite pack,
# Copyright 2021-2021 by chierit.
#
# It's licensed under the terms of the Creative Commons Attribution v4.0 International license.
# (https://creativecommons.org/licenses/by/4.0/)
#
# The original version can be found at:
# https://chierit.itch.io/elementals-ground-monk
#
# Modifications by us:
#   - Extracted sprites from the "3_atk" animation
#   - Added an outline to the monk with the openage outline colour command (RGBA: 0,0,0,252)
#   - Changed orange colour (239,105,47,255) with the openage playercolor colour command (RGBA: 239,105,47,254)
#
# Copyright 2021-2021 the openage authors.
# See copying.md for further legal info.

# openage texture definition file

version 1

imagefile "test_texture.png"

size 208 160

pxformat rgba8 cbits=True

subtex 0 0 28 39 0 0
subtex 28 0 27 37 0 0
subtex 55 0 36 38 0 0
subtex 91 0 40 36 0 0
subtex 91 36 42 37 0 0
subtex 0 73 33 42 0 0
subtex 33 73 36 46 0 0
subtex 69 73 35 37 0 0
subtex 131 0 28 33 0 0
subtex 133 33 27 45 0 0
subtex 104 78 28 46 0 0
subtex 0 124 47 31 0 0
subtex 160 0 48 41 0 0
subtex 160 41 48 41 0 0
subtex 132 82 48 41 0 0
subtex 47 123 51 37 0 0
subtex 0 41 55 31 0 0
subtex 132 123 48 31 0 0


================================================
FILE: assets/textures/CMakeLists.txt
================================================
install(DIRECTORY "."
	DESTINATION "${ASSET_DIR}/textures"
	PATTERN "CMakeLists.txt" EXCLUDE
)


================================================
FILE: assets/textures/torn_paper_edge.docx
================================================
# x,y,w,h,cx,cy
0,0,512,16,0,0


================================================
FILE: buildsystem/CheckCompilerFeatures.cmake
================================================
# Copyright 2015-2021 the openage authors. See copying.md for legal info.

include(CheckCXXSourceRuns)

if(cxx_thread_local IN_LIST CMAKE_CXX_COMPILE_FEATURES)
	set(HAVE_THREAD_LOCAL_STORAGE true)
else()
	set(HAVE_THREAD_LOCAL_STORAGE false)
endif()

check_cxx_source_runs("
#include <compare>
#include <concepts>

class Cat {
public:
	virtual int maunz() const { return 42; };

	auto operator <=>(const Cat &other) const = default;
};

template <typename T>
concept Meowable = std::same_as<T, Cat> || std::derived_from<T, Cat>;

template <Meowable T>
int meow(const T &cat) {
	return cat.maunz();
}

class HouseCat : public Cat {
public:
	int maunz() const override { return 1337; };
};

int main() {
	HouseCat mrr{};
	Cat rrarrr{};
	return meow(mrr) > meow(rrarrr) ? 0 : 1;
}
"
HAVE_REQUIRED_CXX20_SUPPORT
)

if(NOT HAVE_REQUIRED_CXX20_SUPPORT)
	message("

The compiler doesn't support required C++20 features:
  * Concepts
  * Default comparisons
The following versions support these features:
  * clang++ >= 10
  * g++ >= 10
  * Microsoft Visual Studio 2019 >= 16.8
Please upgrade your compiler to build openage.

")
	message(FATAL_ERROR "aborting")
endif()


================================================
FILE: buildsystem/CheckInSourceBuild.cmake
================================================
# Copyright 2015-2018 the openage authors. See copying.md for legal info.

if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
	if(ALLOW_IN_SOURCE_BUILD)
		message("in-source build")
	else()
		message("


In-source builds are disallowed. They are a source of infinite pain,
- cluttering up the source folder
- causing cmake to silently refuse creating out-of-source builds
- overwriting the root Makefile (which contains cleaninsourcebuild)

To perform an out-of-source build,
- mkdir bin; cd bin; cmake ..
- or use ./configure, which will do this automatically

If you really want to perform an in-source build, use -DALLOW_IN_SOURCE_BUILD=TRUE

You need to run 'make cleaninsourcebuild' right now, since this (failed)
attempt already produced traces of an in-source build.
cmake will attempt in-source-builds instead of regular ones until you clean
those traces (remove CMakeCache.txt and CMakeFiles).



")
		message(FATAL_ERROR "aborting")
	endif()
else()
	# Check if the source directory has a generated file.
	if (EXISTS ${CMAKE_SOURCE_DIR}/openage/config.py)
		# Clean the generated files from the source directory.
		execute_process(
			COMMAND git clean -Xf -- libopenage/ openage/
			WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
	endif()
endif()


================================================
FILE: buildsystem/CheckRuntimeDependencies.cmake
================================================
# Copyright 2015-2023 the openage authors. See copying.md for legal info.

# python modules
# a list of imported modules may be obtained via
#
# grep -RE '^ *(import |from [^.])' | cut -d: -f2- | \
#     sed 's/^ *//g' | sort -u | grep -v openage
set(REQUIRED_PYTHON_MODULES "PIL.Image" "PIL.ImageDraw" "numpy" "pygments" "mako.template" "toml" "lz4")

# command-line tools
# example: set(REQUIRED_UTILITIES "foobar")

# Checks if the specified python module exists
#
#     check_python_module_exists(<module> <exists>)
#         <module>: The python module.
#         <exists>: TRUE of FALSE based on the check.
function(check_python_module_exists MODULE EXISTS)
	set(STATEMENT "from importlib import import_module; import_module(\"${MODULE}\")")
	execute_process(
		COMMAND ${PYTHON} -c "${STATEMENT}"
		RESULT_VARIABLE PY_RESULT)

	if(PY_RESULT EQUAL 0)
		set(${EXISTS} TRUE PARENT_SCOPE)
	else()
		set(${EXISTS} FALSE PARENT_SCOPE)
	endif()
endfunction()

# loop through all required python modules to find them
foreach(_PYTHON_MODULE ${REQUIRED_PYTHON_MODULES})
	if("${PY_MOD_${_PYTHON_MODULE}_EXISTS}" STREQUAL "FOUND")
		continue()
	endif()

	check_python_module_exists(${_PYTHON_MODULE} EXISTS)

	if(EXISTS)
		message(STATUS "Checking python3 module ${_PYTHON_MODULE} - Success")
		set(PY_MOD_${_PYTHON_MODULE}_EXISTS "FOUND" CACHE INTERNAL "Python module availability")
	else()
		message(FATAL_ERROR "Checking python3 module ${_PYTHON_MODULE} - Not Found")
	endif()
endforeach()

# loop through all required utilities to find them
foreach(_UTILITY ${REQUIRED_UTILITIES})
	if("${UTILITY_${_UTILITY}_EXISTS}" STREQUAL "FOUND")
		continue()
	endif()

	find_program(${_UTILITY}_EXECUTABLE
		NAMES "${_UTILITY}"
	)

	if(${_UTILITY}_EXECUTABLE)
		message(STATUS "Checking utility program ${_UTILITY} - Success")
		set(UTILITY_${_UTILITY}_EXISTS "FOUND" CACHE INTERNAL "Helper program availability")
	else()
		message(FATAL_ERROR "Checking utility program ${_UTILITY} - Not Found")
	endif()
endforeach()


================================================
FILE: buildsystem/DependencyFetch.cmake
================================================
# Copyright 2017-2017 the openage authors. See copying.md for legal info.

# Fetch project with given name from the Internet.
# Basically wraps ExternalProject and does a nested cmake invocation.
#
# Usage:
#   fetch_project(
#       NAME ${projectname}
#       [DISABLE_UPDATES]
#       ${locationspecification...}
#   )
#
# Arguments:
#   NAME                    -- custom name of the project
#   DISABLE_UPDATES         -- when set, don't do automatic git updates
#   locationspecification   -- passed to ExternalProject_Add
#
# sets in caller scope:
#   ${projectname}_SOURCE_DIR     -- subproject source directory
#   ${projectname}_BINARY_DIR     -- subproject binary directory
#   ${projectname}_SUBPROJ_DIR    -- everything of the subproject
#                                 -- (including src and bin directory)
#
# You need to specify the location with options of
# ExternalProject_Add, for example:
#
# fetch_project(
#     NAME yourmom
#     GIT_REPOSITORY https://github.com/nevergonna/giveyouup
#     GIT_TAG origin/master
# )
#
function(fetch_project)
	cmake_parse_arguments(PROJ "DISABLE_UPDATES" "NAME" "" ${ARGN})

	if(PROJ_NAME STREQUAL "")
		message(FATAL_ERROR "no project name given")
	endif()

	set(PROJ_DIR "${CMAKE_BINARY_DIR}/${PROJ_NAME}-external")
	set(PROJ_DL_DIR "${PROJ_DIR}/dl")
	set(PROJ_SRC_DIR "${PROJ_DIR}/source")
	set(PROJ_BIN_DIR "${PROJ_DIR}/bin")
	set(PROJ_STAMP_DIR "${PROJ_DIR}/stamp")

	# CLion creates this file for multiple projects
	file(REMOVE "${PROJ_DL_DIR}/CMakeCache.txt")

	# create the ExternalProject configuration file
	# for the nested cmake call.
	configure_file(
		"${BUILDSYSTEM_DIR}/templates/ExternalFetch.cmake.in"
		"${PROJ_DL_DIR}/CMakeLists.txt"
		@ONLY
	)

	# run cmake to "configure" the external project.
	# this prepares the download that will be done in the next step.
	execute_process(COMMAND
		${CMAKE_COMMAND}
		"-G${CMAKE_GENERATOR}"
		"-DCMAKE_MAKE_PROGRAM:FILE=${CMAKE_MAKE_PROGRAM}"
		.
		OUTPUT_QUIET
		RESULT_VARIABLE config_ok
		WORKING_DIRECTORY "${PROJ_DL_DIR}"
	)

	if(config_ok)
		message(FATAL_ERROR "Failed to set up external project ${PROJ_NAME}")
	endif()

	# Now actually download the project.
	# This does not "build" it! The "build" is the download execution.
	execute_process(COMMAND
		${CMAKE_COMMAND} --build .
		OUTPUT_QUIET
		RESULT_VARIABLE download_ok
		WORKING_DIRECTORY "${PROJ_DL_DIR}"
	)

	if(download_ok)
		message(FATAL_ERROR "Failed to download external project ${PROJ_NAME}.")
	endif()

	set(${PROJ_NAME}_SOURCE_DIR "${PROJ_SRC_DIR}" PARENT_SCOPE)
	set(${PROJ_NAME}_BINARY_DIR "${PROJ_BIN_DIR}" PARENT_SCOPE)
	set(${PROJ_NAME}_SUBPROJ_DIR "${PROJ_DIR}" PARENT_SCOPE)
endfunction()


================================================
FILE: buildsystem/DetectProjectVersion.cmake
================================================
# Copyright 2015-2023 the openage authors. See copying.md for legal info.

# Determines the version of the project
# stores a full version string with commit hash and number in the variable `PROJECT_VERSION`

# If the project version was already defined or previously retrieved, don't bother.
if(PROJECT_VERSION)
	return()
endif()

# if .git exists, try running git describe
if(IS_DIRECTORY "${CMAKE_SOURCE_DIR}/.git")
	message(STATUS "Set PROJECT_VERSION from git.")
	execute_process(
		COMMAND git describe --tags --long
		WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
		RESULT_VARIABLE _RES
		OUTPUT_VARIABLE PROJECT_VERSION
		ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE
	)

	if(_RES EQUAL 0)
		set(USED_GIT_VERSION 1)
		return()
	endif()
endif()

# Fallback for downloaded zip's or git unavailability
set(PROJECT_VERSION_FILE "${CMAKE_SOURCE_DIR}/openage_version")
if(EXISTS ${PROJECT_VERSION_FILE})
	file(STRINGS ${PROJECT_VERSION_FILE} FILE_DESCRIBE_VERSION)

	STRING(REGEX REPLACE "([0-9]+\\.[0-9]+\\.[0-9]+)"
		   "\\1" PROJECT_VERSION "${FILE_DESCRIBE_VERSION}")
endif()

# Still could not detect the version. Don't worry, raise a warning (shout a curse word?) and move on.
if(NOT PROJECT_VERSION)
	message(WARNING "Could not determine project version.")
	set(PROJECT_VERSION "0.0")
endif()


================================================
FILE: buildsystem/HandleCXXOptions.cmake
================================================
# Copyright 2015-2023 the openage authors. See copying.md for legal info.

# sets CXXFLAGS and compiler for the project

#TODO: integrate PGO (profile-guided optimization) build


include(CheckCXXCompilerFlag)

macro(set_compiler_version_flags TYPE MINIMAL FLAGS INVERS EQTYPE)
	if(${INVERS} CMAKE_CXX_COMPILER_VERSION VERSION_${EQTYPE} ${MINIMAL})
		if(${TYPE} STREQUAL "CXX")
			set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS}")
		elseif(${TYPE} STREQUAL "EXTRA")
			set(EXTRA_FLAGS "${EXTRA_FLAGS} ${FLAGS}")
		else()
			message(FATAL_ERROR "Invalid compiler flag type specified!")
		endif()
	endif()
endmacro()

macro(set_compiler_greater_flags TYPE MINIMAL FLAGS)
	set_compiler_version_flags(${TYPE} ${MINIMAL} ${FLAGS} NOT LESS)
endmacro()

macro(set_compiler_equal_flags TYPE MINIMAL FLAGS)
	set_compiler_version_flags(${TYPE} ${MINIMAL} ${FLAGS} "" EQUAL)
endmacro()

macro(set_compiler_flags TYPE FLAGS)
	set_compiler_version_flags(${TYPE} "0.0" ${FLAGS} "" GREATER)
endmacro()

macro(test_compiler_flag_apply TYPE FLAG NAME DONTRUN)
	if(NOT ${DONTRUN})
		check_cxx_compiler_flag("${FLAG}" ${NAME})
		if(${NAME})
			set_compiler_flags(${TYPE} "${FLAG}")
		endif()
	endif()
endmacro()

macro(set_linker_flags FLAGS)
	set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAGS}")
	set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${FLAGS}")
	set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${FLAGS}")
	set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} ${FLAGS}")
endmacro()

macro(set_cxx_optimize_flags FLAGS)
	set(${BUILD_TYPE_CXX_FLAGS} "${${BUILD_TYPE_CXX_FLAGS}} ${FLAGS}")
endmacro()


set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
if(NOT MSVC)
	set(EXTRA_FLAGS "${EXTRA_FLAGS} -Wall -Wextra -pedantic")
endif()

# set up gold linker features
macro(try_enable_gold_linker)
	# Activate ld.gold instead of the default
	option(USE_LD_GOLD "Use GNU gold linker" ON)
	if(USE_LD_GOLD)
		if(MINGW)
			execute_process(COMMAND ${CMAKE_CXX_COMPILER} -Wl,--major-image-version,0,--minor-image-version,0 -fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
		else()
			execute_process(COMMAND ${CMAKE_CXX_COMPILER} -fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
		endif()
		if("${LD_VERSION}" MATCHES "GNU gold")
			set(HAVE_LD_GOLD TRUE)
			set_linker_flags("-fuse-ld=gold")
		else()
			set(HAVE_LD_GOLD FALSE)
			message(WARNING "GNU gold linker isn't available, using the default system linker.")
		endif()
	endif()

	# do splitdebug by default when in debug mode
	set(DEBUG_FISSION_DEFAULT OFF)
	if(HAVE_LD_GOLD AND CMAKE_BUILD_TYPE STREQUAL "Debug")
		check_cxx_compiler_flag("-gsplit-dwarf" HAVE_GSPLIT_DWARF_SUPPORT)
		if(HAVE_GSPLIT_DWARF_SUPPORT)
			set(DEBUG_FISSION_DEFAULT ON)
		endif()
	endif()

	# https://gcc.gnu.org/wiki/DebugFission
	option(DEBUG_FISSION "Enable Debug Fission" DEBUG_FISSION_DEFAULT)
	if(DEBUG_FISSION)
		if(NOT HAVE_LD_GOLD)
			message(FATAL_ERROR "GNU gold linker required for Debug Fission")
		endif()
		set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -gsplit-dwarf")
		set_linker_flags("-Wl,--gdb-index")
	endif()
endmacro()

# check for compiler versions
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
	set_compiler_greater_flags("CXX" 4.9 "-fdiagnostics-color=auto")
	set_compiler_greater_flags("EXTRA" 5.0 "-Wsuggest-override")
	try_enable_gold_linker()

elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
	set_compiler_flags("EXTRA" "-Wno-gnu-statement-expression")
	try_enable_gold_linker()

	if(APPLE)
		set_compiler_flags("CXX" "-stdlib=libc++")
	endif()

elseif(MSVC)
	# Don't worry. You're not alone. If you face an issue, just ask.

	# Enable multi processor compilation on MSVC
	set_compiler_flags("CXX" "/MP")

	return() # The following flag specifications don't apply.

else() # "Intel", etc..
	message(WARNING "Using untested compiler, at least I hope it's free software. Continue on your own, warrior.")
endif()

# optional code warnings from include-what-you-use
if("${CXX_INCLUDE_WHAT_YOU_USE}" STREQUAL "warn")
	set(CXX_INCLUDE_WHAT_YOU_USE)
elseif("${CXX_INCLUDE_WHAT_YOU_USE}" STREQUAL "error")
	set(CXX_INCLUDE_WHAT_YOU_USE "--error_always")
endif()

# optimization settings.
# TODO: multi-configuration support for xcode, vstudio, ...
#       the following code just makes sense for single-config
#       generation, e.g. makefiles.
#       we'd have to perform the flag generation for other types as well.

# these flags will now be extended by the following code.
set(CMAKE_CXX_FLAGS_DEBUG "-g")
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG")

# If CXX_OPTIMIZATION_LEVEL was not provided, default to auto
if("${CXX_OPTIMIZATION_LEVEL}" STREQUAL "")
	set(CXX_OPTIMIZATION_LEVEL "auto")
endif()

if("${CXX_OPTIMIZATION_LEVEL}" STREQUAL "auto")
	if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
		set(CXX_OPTIMIZATION_LEVEL "g")
	else()
		set(CXX_OPTIMIZATION_LEVEL "3")
	endif()
endif()

if("${CXX_OPTIMIZATION_LEVEL}" STREQUAL "0")
	set_cxx_optimize_flags("-O0")
elseif("${CXX_OPTIMIZATION_LEVEL}" STREQUAL "1")
	set_cxx_optimize_flags("-O1")
elseif("${CXX_OPTIMIZATION_LEVEL}" STREQUAL "2")
	set_cxx_optimize_flags("-O2")
elseif("${CXX_OPTIMIZATION_LEVEL}" STREQUAL "3")
	set_cxx_optimize_flags("-O3")
elseif("${CXX_OPTIMIZATION_LEVEL}" STREQUAL "g")
	if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
		set_cxx_optimize_flags("-Og")
	else()
		set_cxx_optimize_flags("-O0")
	endif()
elseif("${CXX_OPTIMIZATION_LEVEL}" STREQUAL "max")
	set_cxx_optimize_flags("-O3 -march=native")

	if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
		include(ProcessorCount)
		ProcessorCount(N)
		if(NOT N EQUAL 0)
			set_cxx_optimize_flags("-flto=${N}")
			set_linker_flags("-flto=${N}")
		endif()
	endif()
endif()


# sanitizing options

if(NOT CXX_SANITIZE_MODE)
	set(CXX_SANITIZE_MODE "none")
endif()

if("${CXX_SANITIZE_MODE}" STREQUAL "none")
	# Do nothing
	if("${CXX_SANITIZE_FATAL}")
		message(WARNING "CXX_SANITIZE_FATAL is only valid when CXX_SANITIZE_MODE is not none")
	endif()
else()
	set_compiler_flags("CXX" "-fno-omit-frame-pointer")
	if("${CXX_SANITIZE_FATAL}" AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
		set_compiler_flags("CXX" "-fno-sanitize-recover")
	endif()

	if("${CXX_SANITIZE_MODE}" STREQUAL "yes")
		set_compiler_flags("CXX" "-fsanitize=address")
		set_compiler_flags("CXX" "-fsanitize=undefined")
	elseif("${CXX_SANITIZE_MODE}" STREQUAL "mem")
		if(NOT APPLE)
			set_compiler_flags("CXX" "-fsanitize=memory")
		endif()
	elseif("${CXX_SANITIZE_MODE}" STREQUAL "thread")
		if(NOT APPLE)
			set_compiler_flags("CXX" "-fsanitize=thread")
		endif()
		if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
			set_compiler_flags("CXX" "-fPIC")
			set_compiler_flags("CXX" "-pie")
		endif()
	else()
		message(WARNING "Unknown sanitizer mode provided: ${CXX_SANITIZE_MODE}")
	endif()
endif()


================================================
FILE: buildsystem/HandlePythonOptions.cmake
================================================
# Copyright 2015-2025 the openage authors. See copying.md for legal info.

# finds the python interpreter, install destination and extension flags.

# the Python version number requirement is in modules/FindPython_test.cpp
find_package(Python ${PYTHON_MIN_VERSION} REQUIRED)

find_package(Cython ${CYTHON_MIN_VERSION})
if(NOT CYTHON_FOUND)
	message("Checking for alternative Cython fallback version (>=${CYTHON_MIN_VERSION_FALLBACK} AND <=${CYTHON_MAX_VERSION_FALLBACK})")
	find_package(Cython ${CYTHON_MIN_VERSION_FALLBACK} QUIET)
	if(CYTHON_VERSION VERSION_LESS ${CYTHON_MIN_VERSION} AND CYTHON_VERSION VERSION_GREATER ${CYTHON_MAX_VERSION_FALLBACK})
		message(FATAL_ERROR "Cython version ${CYTHON_VERSION} is not compatible")
	else()
		message("Compatible Cython version ${CYTHON_VERSION} found")
	endif()
endif()

py_get_config_var(EXT_SUFFIX PYEXT_SUFFIX)
if(MINGW)
	string(REGEX REPLACE "dll" "pyd" PYEXT_SUFFIX "${PYEXT_SUFFIX}")
endif()

# This is the only useful thing after cleaning up what python suggests
if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
	set(PYEXT_CXXFLAGS "-fwrapv")
endif()


# numpy deprecated api
# http://docs.cython.org/en/latest/src/userguide/source_files_and_compilation.html#configuring-the-c-build
if(CYTHON_VERSION VERSION_GREATER_EQUAL 3)
	set(PYEXT_CXXFLAGS "${PYEXT_CXXFLAGS} -DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION")
else()

	# suppress #warning about deprecated numpy api
	if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
		set(PYEXT_CXXFLAGS "${PYEXT_CXXFLAGS} -Wno-cpp")
	elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
		set(PYEXT_CXXFLAGS "${PYEXT_CXXFLAGS} -Wno-#warnings")
	endif()
endif()

# silence cython+python3.8 tp_print deprecation warning
# https://github.com/cython/cython/pull/3201
# https://github.com/cython/cython/issues/3474
if(PYTHON_VER VERSION_GREATER_EQUAL 3.8 AND PYTHON_VERSION VERSION_LESS 3.9)
	set(PYEXT_CXXCLAGS "${PYEXT_CXXCLAGS}" "-Wno-deprecated-declarations")
endif()

set(PYEXT_LIBRARY "${PYTHON_LIBRARIES}")
message("PYTHON_LIBRARIES: " "${PYTHON_LIBRARIES}")
#Windows always uses optimized version of Python lib
if(WIN32 AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
	#get index of string "optimized" and increment it by 1 so index points at the path of the optimized lib
	list(FIND PYEXT_LIBRARY "optimized" _index)
	if(${_index} GREATER -1)
		MATH(EXPR _index "${_index}+1")
		list(GET PYEXT_LIBRARY ${_index} PYEXT_LIBRARY)
	endif()
	message("force linking to python release lib, instead of debug lib when cythonising")
	set(force_optimized_lib_flag "--force_optimized_lib")
endif()

set(PYEXT_INCLUDE_DIRS "${PYTHON_INCLUDE_DIRS};${NUMPY_INCLUDE_DIR}")

if(NOT CMAKE_PY_INSTALL_PREFIX)
	if(MSVC)
		set(CMAKE_PY_INSTALL_PREFIX "python")
	else()
		# get site-packages directory, prepended with cmake's install prefix
		py_exec("import sys, sysconfig, os; print(os.path.join('${CMAKE_INSTALL_PREFIX}', os.path.relpath(sysconfig.get_path('purelib'), os.path.normpath(sys.prefix))))" PREFIX)
		set(CMAKE_PY_INSTALL_PREFIX "${PREFIX}")
	endif()
endif()


================================================
FILE: buildsystem/__init__.py
================================================
# Copyright 2015-2020 the openage authors. See copying.md for legal info.

"""
CMake build helpers; see doc/buildsystem.md for further info.

Modules in the 'buildsystem' package are not intended to be installed
with openage, or used from outside the build process; otherwise, they
would be in the 'openage' package.
"""


================================================
FILE: buildsystem/check_py_file_list.py
================================================
# Copyright 2015-2021 the openage authors. See copying.md for legal info.

"""
Tests whether the files listed via add_py_module are consistent with the
.py files in the openage directory.
"""

import argparse
import os
import sys


def main():
    """ CLI entry point """
    cli = argparse.ArgumentParser()
    cli.add_argument('py_file_list', help=(
        "semicolon-separated list of listed .py files"
    ))
    cli.add_argument('py_module_dir', help=(
        "directory containing the python module to check"
    ))
    cli.add_argument('-v', '--verbose', action='store_true', help=(
        "produce verbose output"
    ))
    args = cli.parse_args()

    openage_dir = os.path.realpath(args.py_module_dir)

    listed = set()
    with open(args.py_file_list, encoding='utf8') as fileobj:
        for filename in fileobj.read().strip().split(';'):
            filepath = os.path.realpath(os.path.normpath(filename))
            if filepath.startswith(openage_dir):
                listed.add(filepath)
            elif args.verbose:
                print("Ignoring " + filepath + " outside " + openage_dir)

    if args.verbose:
        print("Files listed in " + args.py_file_list + ":",
              *sorted(listed), sep='\n\t')

    actual = set()
    for dirname, _, files in os.walk(openage_dir):
        dirname = os.path.realpath(os.path.abspath(dirname))
        for filename in files:
            if filename.endswith('.py'):
                actual.add(os.path.join(dirname, filename))

    if args.verbose:
        print("Files available:", *sorted(actual), sep='\n\t')

    success = True
    for filename in sorted(actual - listed):
        success = False
        print("file was not listed via add_py_module: " +
              os.path.relpath(filename, openage_dir))

    for filename in sorted(listed - actual):
        success = False
        print("file was listed via add_py_module but does not exist: " +
              os.path.relpath(filename, openage_dir))

    if success:
        return 0

    return 1


if __name__ == '__main__':
    sys.exit(main())


================================================
FILE: buildsystem/codecompliance/__init__.py
================================================
# Copyright 2015-2016 the openage authors. See copying.md for legal info.

"""
Code compliance checker module

Integrated into the root Makefile.
"""


================================================
FILE: buildsystem/codecompliance/__main__.py
================================================
# Copyright 2014-2025 the openage authors. See copying.md for legal info.

"""
Entry point for the code compliance checker.
"""

import argparse
import importlib
import os
import shutil
import subprocess
import sys

from .util import log_setup


def parse_args():
    """ Returns the raw argument namespace. """

    cli = argparse.ArgumentParser()
    check_types = cli.add_mutually_exclusive_group()
    check_types.add_argument("--fast", action="store_true",
                             help="do all checks that can be performed quickly")
    check_types.add_argument("--merge", action="store_true",
                             help="do all checks that are required before merges to master")
    check_types.add_argument("--all", action="store_true",
                             help="do all checks, even the really slow ones")

    cli.add_argument("--only-changed-files", metavar='GITREF',
                     help=("slow checks are only done on files that have "
                           "changed since GITREF."))
    cli.add_argument("--authors", action="store_true",
                     help=("check whether all git authors are in copying.md. "
                           "repo must be a git repository."))
    cli.add_argument("--clang-tidy", action="store_true",
                     help=("Check the C++ code with clang-tidy. Make sure you have build the "
                           "project with ./configure --clang-tidy or have set "
                           "CMAKE_CXX_CLANG_TIDY for your CMake build."))
    cli.add_argument("--cppstyle", action="store_true",
                     help="check the cpp code style")
    cli.add_argument("--cython", action="store_true",
                     help="check if cython is turned off")
    cli.add_argument("--headerguards", action="store_true",
                     help="check all header guards")
    cli.add_argument("--legal", action="store_true",
                     help="check whether all sourcefiles have legal headers")
    cli.add_argument("--filemodes", action="store_true",
                     help=("check whether files in the repo have the "
                           "correct access bits (-> 0644) "))
    cli.add_argument("--pylint", action="store_true",
                     help="run pylint on the python code")
    cli.add_argument("--pystyle", action="store_true",
                     help=("check whether the python code complies with "
                           "(a selected subset of) pep8."))
    cli.add_argument("--textfiles", action="store_true",
                     help="check text files for whitespace issues")
    cli.add_argument("--test-git-change-years", action="store_true",
                     help=("when doing legal checks, test whether the "
                           "copyright year matches the git history."))

    cli.add_argument("--fix", action="store_true",
                     help="try to automatically fix the found issues")

    cli.add_argument("-v", "--verbose", action="count", default=0,
                     help="increase program verbosity")
    cli.add_argument("-q", "--quiet", action="count", default=0,
                     help="decrease program verbosity")

    args = cli.parse_args()
    process_args(args, cli.error)

    return args


def process_args(args, error):
    """
    Sanitizes the given argument namespace, modifying it in the process.

    Calls error (with a string argument) in case of errors.
    """
    # this method is very flat; artificially nesting it would be bullshit.
    # pylint: disable=too-many-branches

    # set up log level
    log_setup(args.verbose - args.quiet)

    if args.fast or args.merge or args.all:
        # enable "fast" tests
        args.authors = True
        args.cppstyle = True
        args.cython = True
        args.headerguards = True
        args.legal = True
        args.filemodes = True
        args.textfiles = True

    if args.merge or args.all:
        # enable tests that are required before merging to master
        args.pystyle = True
        args.pylint = True
        args.test_git_change_years = True

    if args.all:
        # enable tests that take a bit longer
        args.clang_tidy = True

    if not any((args.headerguards, args.legal, args.authors, args.pystyle,
                args.cppstyle, args.cython, args.test_git_change_years,
                args.pylint, args.filemodes, args.textfiles, args.clang_tidy)):
        error("no checks were specified")

    has_git = bool(shutil.which('git'))
    is_git_repo = os.path.exists('.git')

    if args.only_changed_files and not all((has_git, is_git_repo)):
        error("can not check only changed files: git is required")

    if args.authors:
        if not all((has_git, is_git_repo)):
            # non-fatal fail
            print("can not check author list for compliance: git is required")
            args.authors = False

    if args.test_git_change_years:
        if not args.legal:
            error("--test-git-change-years may only be passed with --legal")

        if not all((has_git, is_git_repo)):
            error("--test-git-change-years requires git")

    if args.pystyle:
        if not importlib.util.find_spec('pep8') and \
           not importlib.util.find_spec('pycodestyle'):

            error("pep8 or pycodestyle python module "
                  "required for style checking")

    if args.pylint:
        if not importlib.util.find_spec('pylint'):
            error("pylint python module required for linting")

    if args.clang_tidy:
        if not shutil.which('clang-tidy'):
            error("--clang-tidy requires clang-tidy to be installed")


def get_changed_files(gitref):
    """
    return a list of changed files
    """
    invocation = ['git', 'diff', '--name-only', '--diff-filter=ACMRTUXB',
                  gitref]

    try:
        file_list = subprocess.check_output(invocation)

    except subprocess.CalledProcessError as exc:
        raise RuntimeError(
            "could not determine list of recently-changed files with git"
        ) from exc

    return set(file_list.decode('ascii').strip().split('\n'))


def main(args):
    """
    Takes an argument namespace as returned by parse_args.

    Calls find_all_issues(main args, list of files to consider)

    Returns True if no issues were found.
    """
    if args.only_changed_files:
        check_files = get_changed_files(args.only_changed_files)
    else:
        check_files = None

    auto_fixes = []
    fixes_possible = False

    issues_count = 0
    for title, text, apply_fix in find_all_issues(args, check_files):
        issues_count += 1
        print(f"\x1b[33;1mWARNING\x1b[m {title}: {text}")

        if apply_fix:
            fixes_possible = True

            if args.fix:
                print("        This will be fixed automatically.")
                auto_fixes.append(apply_fix)
            else:
                print("        This can be fixed automatically.")

        # nicely seperate warnings
        print()

    if args.fix and auto_fixes:
        print(f"\x1b[33;1mApplying {len(auto_fixes):d} automatic fixes...\x1b[m")

        for auto_fix in auto_fixes:
            print(auto_fix())
            issues_count -= 1

        print()

    if issues_count > 0:
        plural = "s" if issues_count > 1 else ""

        if args.fix and auto_fixes:
            remainfound = f"remain{plural}"
        else:
            remainfound = ("were" if issues_count > 1 else "was") + " found"

        print(f"==> \x1b[33;1m{issues_count} issue{plural}\x1b[m {remainfound}.")

        if not args.fix and fixes_possible:
            print("When invoked with --fix, I can try "
                  "to automatically resolve some of the issues.\n")

    return issues_count == 0


def find_all_issues(args, check_files=None):
    """
    Invokes all the individual issue checkers, and yields their returned
    issues.

    If check_files is not None, all other files are ignored during the
    more resource-intense checks.
    That is, check_files is the set of files to verify.

    Yields tuples of (title, text) that are displayed as warnings.
    """

    # pylint: disable=too-many-function-args, no-value-for-parameter
    # no-value-for-parameter has to be used because pylint is dumb

    if args.headerguards:
        from .headerguards import find_issues
        yield from find_issues('libopenage')

    if args.authors:
        from .authors import find_issues
        yield from find_issues()

    if args.pystyle:
        from .pystyle import find_issues
        yield from find_issues(check_files, ('openage', 'buildsystem', 'etc/gdb_pretty'))

    if args.cython:
        from buildsystem.codecompliance.cython import find_issues
        yield from find_issues(check_files, ('openage',))

    if args.cppstyle:
        from .cppstyle import find_issues
        yield from find_issues(check_files, ('libopenage',))

    if args.pylint:
        from .pylint import find_issues
        yield from find_issues(check_files, ('openage', 'buildsystem', 'etc/gdb_pretty'))

    if args.textfiles:
        from .textfiles import find_issues
        yield from find_issues(
            ('openage', 'libopenage', 'buildsystem', 'doc', 'legal', 'etc/gdb_pretty'),
            ('.pxd', '.pyx', '.pxi', '.py',
             '.h', '.cpp', '.template',
             '', '.txt', '.md', '.conf',
             '.cmake', '.in', '.yml', '.supp', '.desktop'))

    if args.legal:
        from .legal import find_issues
        yield from find_issues(check_files,
                               ('openage', 'buildsystem', 'libopenage', 'etc/gdb_pretty'),
                               args.test_git_change_years)

    if args.filemodes:
        from .modes import find_issues
        yield from find_issues(check_files, ('openage', 'buildsystem',
                                             'libopenage', 'etc/gdb_pretty'))
    if args.clang_tidy:
        from .clangtidy import find_issues
        yield from find_issues(check_files, ('libopenage', ))


if __name__ == '__main__':
    if main(parse_args()):
        sys.exit(0)
    else:
        sys.exit(1)


================================================
FILE: buildsystem/codecompliance/authors.py
================================================
# Copyright 2014-2024 the openage authors. See copying.md for legal info.

"""
Checks whether all authors are properly listed in copying.md.
"""

import re

import logging

from .util import Strlazy


def deobfuscate_email(string):
    """
    Should reveal the original email address passed into obfuscate_email

    deobfuscate_email('first dawt last+tag à gmail dawt com')
    = 'first.last+tag@gmail.com'
    """
    replacements = {
        ' dawt ': '.',
        ' à ': '@'
    }

    for key, value in replacements.items():
        string = string.replace(key, value)

    return string


def get_author_emails_copying_md():
    """
    yields all emails from the author table in copying.md

    they must be part of a line like

    |     name     |    nick    |    email    |
    """
    with open("copying.md", encoding='utf8') as fobj:
        for line in fobj:
            match = re.match(r"^.*\|[^|]*\|[^|]*\|([^|]+)\|.*$", line)
            if not match:
                continue

            email = match.group(1).strip()
            if 'à' in email:
                email = deobfuscate_email(email)

            if not any(email.startswith(prefix) for prefix in ("E-Mail", "-" * 15))\
               and '@' not in email:
                raise ValueError(f"no @ or à was found in email: {email}")

            yield email


def get_author_emails_git_shortlog(exts):
    """
    yields emails of all authors that have authored any of the files ending
    in exts (plus their templates)

    parses the output of git shortlog -sne
    """
    from subprocess import Popen, PIPE

    invocation = ['git', 'shortlog', '-sne', '--']
    for ext in exts:
        invocation.append(f"*{ext}")
        invocation.append(f"*{ext}.in")
        invocation.append(f"*{ext}.template")

    with Popen(invocation, stdout=PIPE) as invoc:
        output = invoc.communicate()[0]

    for line in output.decode('utf-8', errors='replace').split('\n'):
        match = re.match("^ +[0-9]+\t[^<]*\\<(.*)\\>$", line)
        if match:
            yield match.group(1).lower()


def find_issues():
    """
    compares the output of git shortlog -sne to the authors table in copying.md

    prints all discrepancies, and returns False if one is detected.
    """
    relevant_exts = ('.cpp', '.h', '.py', '.pyi', '.pyx', '.cmake',
                     '.qml')

    copying_md_emails = set(get_author_emails_copying_md())
    logging.debug("scanned authors in copying.md:\n%s",
                  Strlazy(lambda: f"{chr(10).join(sorted(copying_md_emails))}"))

    git_shortlog_emails = set(get_author_emails_git_shortlog(relevant_exts))
    logging.debug("scanned authors from git shortlog:\n%s",
                  Strlazy(lambda: f"{chr(10).join(sorted(git_shortlog_emails))}"))

    # look for git emails that are unlisted in copying.md
    for email in git_shortlog_emails - copying_md_emails:
        if email in {'coop@sft.mx', '?'}:
            continue

        yield (
            "author inconsistency",
            f"{email}\n\temail appears in git log, but not in copying.md or .mailmap",
            None
        )


================================================
FILE: buildsystem/codecompliance/clangtidy.py
================================================
# Copyright 2024-2024 the openage authors. See copying.md for legal info.

"""
Checks clang-tidy errors on cpp files
"""

import subprocess
from .cppstyle import filter_file_list
from .util import findfiles


def find_issues(check_files, dirnames):
    """
    Invoke clang-tidy to check C++ files for issues.
    Yields issues found by clang-tidy in real-time.
    """
    # Specify the checks to include
    # 4 checks we focus on
    checks_to_include = [
        'clang-analyzer-*',
        'bugprone-*',
        'concurrency-*',
        'performance-*'
    ]
    # Create the checks string
    checks = ', '.join(checks_to_include)

    # Invocation command
    invocation = ['clang-tidy', f'-checks=-*,{checks}']

    # Use utility functions from util.py and cppstyle.py
    if check_files is not None:
        filenames = list(filter_file_list(check_files, dirnames))
    else:
        filenames = list(filter_file_list(findfiles(dirnames), dirnames))

    if not filenames:
        print("No files to check.")
        return  # No files to check

    for filename in filenames:
        # Run clang-tidy for each file
        print(f"Starting clang-tidy check on file: {filename}")
        try:
            with subprocess.Popen(
                invocation + [filename],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True
            ) as process:
                # Stream output in real-time
                while True:
                    output = process.stdout.readline()
                    if output:
                        yield ("clang-tidy output", output.strip(), None)
                    elif process.poll() is not None:
                        break

                # Capture remaining errors (if any)
                for error_line in process.stderr:
                    yield ("clang-tidy error", error_line.strip(), None)

        # Handle exception
        except subprocess.SubprocessError as exc:
            yield (
                "clang-tidy error",
                f"An error occurred while running clang-tidy on {filename}: {str(exc)}",
                None
            )


================================================
FILE: buildsystem/codecompliance/cppstyle.py
================================================
# Copyright 2015-2017 the openage authors. See copying.md for legal info.

"""
Checks some code style rules for cpp files.
"""

import re

from .util import findfiles, readfile, issue_str_line

# spaces missing in `if () {` and `for`, `while`, ...
MISSING_SPACES_RE = re.compile(
    # on of the folowing, the first group is used for the column where
    # the pointer is going to show
    r"(?:"
    # a ) folowed by a { without a space between
    r"(?:\)(\{))|"
    # a if/for/while folowed by a ( without a space between
    r"(?:\s+(?:if|for|while)(\())"
    r")"
)

# extra spaces before a ;
EXTRA_SPACES_RE = re.compile(
    # on of the folowing, the first group is used for the column where
    # the pointer is going to show
    r"(?:"
    # a space before a ";"
    r"(?:(\s+);)"
    r")"
)

# indentation fails looking at a file
INDENT_FAIL_RE = re.compile(
    # leading whitespace fail
    r"(?:"
    r"(\n\t*[ ]+\t+)"         # \n tab* space+ tab+
    r")"
)

# we need both because we look at the file first.
# indentation fails when looking at a line
INDENT_FAIL_LINE_RE = re.compile(
    # leading whitespace fail
    r"(?:"
    r"(^\t*[ ]+\t+)"          # tab* space+ tab+
    r")"
)


def filter_file_list(check_files, dirnames):
    """
    Yields all those files in check_files that are in one of the directories
    and end in '.cpp' or '.h' and some other conditions.
    """
    for filename in check_files:
        if not (filename.endswith('.cpp') or filename.endswith('.h')):
            continue

        if filename.endswith('.gen.h') or filename.endswith('.gen.cpp'):
            # TODO all this for now, until someone fixes the codegen.
            continue

        if any(filename.startswith(dirname) for dirname in dirnames):
            yield filename


def find_issues(check_files, dirnames):
    """
    Finds all issues in the given directories (filtered by check_files).
    """

    if check_files is not None:
        filenames = filter_file_list(check_files, dirnames)
    else:
        filenames = filter_file_list(findfiles(dirnames), dirnames)

    for filename in filenames:
        data = readfile(filename)
        analyse_each_line = False

        if MISSING_SPACES_RE.search(data) or\
           EXTRA_SPACES_RE.search(data) or\
           INDENT_FAIL_RE.search(data):

            analyse_each_line = True

        # if there are possible issues perform a per line analysis
        if analyse_each_line:
            yield from find_issues_with_lines(data, filename)


def find_issues_with_lines(data, filename):
    """
    Checks a file for issues per line
    """

    for num, line in enumerate(data.splitlines(True), start=1):

        match = MISSING_SPACES_RE.search(line)
        if match:
            start = match.start(1) + match.start(2)
            end = start + 1
            yield issue_str_line("Missing space",
                                 filename, line, num,
                                 (start, end))

        match = EXTRA_SPACES_RE.search(line)
        if match:
            yield issue_str_line("Extra space",
                                 filename, line, num,
                                 (match.start(1), match.end(1)))

        match = INDENT_FAIL_LINE_RE.search(line)
        if match:
            yield issue_str_line("Wrong indentation",
                                 filename, line, num,
                                 (match.start(1), match.end(1)))


================================================
FILE: buildsystem/codecompliance/cython.py
================================================
# Copyright 2021-2021 the openage authors. See copying.md for legal info.

"""
Verifies that Cython directives for profiling are deactivated.
"""

import re

from buildsystem.codecompliance.util import issue_str_line

from .util import findfiles, readfile


GLOBAL_PROFILE_DIREC = re.compile((
    # global profiling directive for a file
    r"^(# cython: .*(profile=True|linetrace=True).*\n)"
))

FUNC_PROFILE_DIREC = re.compile((
    # profiling for single functions
    r"@cython\.profile\(True\)"
))


def filter_file_list(check_files, dirnames):
    """
    Yields all those files in check_files that are in one of the directories
    and end in '.py'x.
    """
    for filename in check_files:
        if not filename.endswith('.pyx'):
            continue

        if any(filename.startswith(dirname) for dirname in dirnames):
            yield filename


def find_issues(check_files, dirnames):
    """
    Finds all issues in the given directories (filtered by check_files).
    """
    if check_files:
        filenames = filter_file_list(check_files, dirnames)

    else:
        filenames = findfiles(dirnames, ('.pyx',))

    for filename in filenames:
        data = readfile(filename)

        for num, line in enumerate(data.splitlines(True), start=1):
            match = GLOBAL_PROFILE_DIREC.match(line)
            if match:
                yield issue_str_line("cython profiling activated in header",
                                     filename, line, num,
                                     (match.start(1), match.end(1)))

            match = FUNC_PROFILE_DIREC.search(line)
            if match:
                yield issue_str_line("cython function profiling activated in file",
                                     filename, line, num,
                                     (match.start(0), match.end(0)))


================================================
FILE: buildsystem/codecompliance/headerguards.py
================================================
# Copyright 2014-2021 the openage authors. See copying.md for legal info.

"""
Verifies the guard macros of all C++ header files.
"""

import re

from .util import findfiles, readfile


class HeaderIssue(Exception):
    """ Some issue was detected with the Header guard. """


GUARD_RE = re.compile((
    # allow any number of comments or empty lines
    "^(\\n|(#|//).*\\n)*"

    # the header guard
    "#pragma once\n"
))

NO_GUARD_REQUIRED_RE = re.compile((
    # allow any number of comments or empty lines
    "^(\\n|(#|//).*\\n)*"

    # require comment "has no header guard"
    "(#|//) has no header guard:"
))


def find_issues(dirname):
    """
    checks all headerguards in header files in the cpp folders.
    """
    for fname in findfiles((dirname,), ('.h',)):
        try:
            data = readfile(fname)

            if NO_GUARD_REQUIRED_RE.match(data):
                # this file needs no header guard, for the reason
                # detailed in the comment.
                continue

            match = GUARD_RE.match(data)
            if not match:
                raise HeaderIssue("No valid header guard found (e.g. #pragma once)")

        except HeaderIssue as exc:
            yield (f"header guard issue in {fname}", exc.args[0], None)


================================================
FILE: buildsystem/codecompliance/legal.py
================================================
# Copyright 2014-2023 the openage authors. See copying.md for legal info.

"""
Checks the legal headers of all files.
"""

from datetime import date
import re
from subprocess import Popen, PIPE

from .util import findfiles, readfile, writefile, has_ext, SHEBANG


OPENAGE_AUTHORS = (
    "Copyright (?P<crstart>\\d{4})-(?P<crend>\\d{4}) the openage authors\\."
)
OPENAGE_AUTHORTEMPLATE = (
    "Copyright {crstart}-{crend} the openage authors."
)

NATIVELEGALHEADER = re.compile(
    "^"
    # Allow shebang line, followed by an optional empty line.
    "(" + SHEBANG + ")?"

    # Next line must be the copyright line.
    "(#|//) " + OPENAGE_AUTHORS + " See copying\\.md for legal info\\.\n"
)

THIRDPARTYLEGALHEADER = re.compile(
    "^"
    # 3rd-party copyright/license
    "(#|//) This file (was (taken|adapted)|contains (data|code)) from .*\n"
    "(#|//) Copyright \\d{4}-\\d{4} .*\n"
    "(#|//) .*license.*\n"

    # any number of lines containing further 3rd-party copyright info
    "((#|//) .*\\n)*"

    # the openage copyright
    "(#|//) (Modifications|Other (data|code)|Everything else) " +
    OPENAGE_AUTHORS + "\n"
    "(#|//) See copying\\.md for further legal info\\.\n")

# Empty files (consisting of only comments) don't require a legal header.
EMPTYFILE = re.compile("^(((#|//) .*)?\n)*$")

# cython-generated files
CYTHONGENERATED = re.compile("^[^\\n]*(Generated by Cython |failed Cython compilation.)")


# all those files will be checked.
EXTENSIONS_REQUIRING_LEGAL_HEADERS = {
    '.h', '.cpp', '.py', '.pyx', '.pxi', '.cmake', '.h.in',
    '.cpp.in', '.py.in', '.h.template', '.cpp.template',
    '.py.template', '.qml'
}


def get_git_change_year(filename):
    """ Returns git-log's opinion on when the file was last changed. """

    invocation = [
        'git', 'log', '-1', '--format=%ad', '--date=short', '--no-merges', '--',
        filename
    ]

    with Popen(invocation, stdout=PIPE) as proc:
        output = proc.communicate()[0].decode('utf-8', errors='ignore').strip()

        if proc.returncode != 0 or not output:
            # git doesn't know about the file
            return None

    return int(output[:4])


def match_legalheader(data):
    """
    Tests whether data matches any of the regular expressions,
    and returns a tuple of (matching header regex, match).
    """
    for hdr in (NATIVELEGALHEADER,
                THIRDPARTYLEGALHEADER,
                EMPTYFILE,
                CYTHONGENERATED):

        match = re.match(hdr, data)
        if match is not None:
            return hdr, match

    raise ValueError("no match found")


def create_year_fix(filename, file_content, expected_end_year,
                    found_start_year, headertype):
    """
    Create a function that, when called, fixes the copyright header.
    """

    # check if a fix can be created
    if headertype not in {NATIVELEGALHEADER, THIRDPARTYLEGALHEADER}:
        return None

    def year_fix_function():
        """
        Store the file with correct copyright years.
        """

        fixed_file, success = re.subn(
            OPENAGE_AUTHORS,
            OPENAGE_AUTHORTEMPLATE.format(crstart=found_start_year,
                                          crend=expected_end_year),
            file_content
        )

        if not success:
            raise ValueError("copyright year fix did not suceeed")

        writefile(filename, fixed_file)

        return f"Copyright for {filename} was fixed."

    return year_fix_function


def test_headers(check_files, paths, git_change_years, third_party_files):
    """ Tests all in-sourcefile legal headers. """

    if not git_change_years:
        print("warning: I won't check if the copyright matches the git history.")
        print("         Run with --test-git-change-years to enable the check.")

    # determine all uncommited files from git.
    # those definitely need the current year in the copyright message.
    with Popen(['git', 'diff', '--name-only', 'HEAD'], stdout=PIPE) as proc:
        uncommited = set(proc.communicate()[0].decode('ascii').strip().split('\n'))

    current_calendar_year = date.today().year

    for filename in findfiles(paths, EXTENSIONS_REQUIRING_LEGAL_HEADERS):
        try:
            file_content = readfile(filename)
            headertype, match = match_legalheader(file_content)
        except ValueError:
            yield (
                "Legal header missing or invalid",
                (filename + "\nSee copying.md for a template"),
                None
            )
            continue

        if headertype is THIRDPARTYLEGALHEADER:
            third_party_files.add(filename)

        try:
            found_start_year = int(match.group('crstart'))
            found_end_year = int(match.group('crend'))
        except IndexError:
            # this header type has/needs no copyright years
            # (e.g. empty file)
            continue

        expected_end_year = None
        if filename in uncommited:
            expected_end_year = current_calendar_year
        elif git_change_years:
            if check_files is None or filename in check_files:
                expected_end_year = get_git_change_year(filename)

        if expected_end_year is None:
            continue

        if found_end_year != expected_end_year:

            fix = create_year_fix(
                filename,
                file_content,
                expected_end_year,
                found_start_year,
                headertype
            )

            yield (
                "Bad copyright year",
                (filename + "\n" +
                 f"\tExpected {expected_end_year}\n" +
                 f"\tFound    {found_end_year}"),
                fix
            )


def find_issues(check_files, paths, git_change_years=False):
    """
    Tests all source files for the required legal headers.
    """

    third_party_files = set()

    yield from test_headers(
        check_files, paths, git_change_years, third_party_files)

    # test whether all third-party files are listed in copying.md
    listed_files = set()
    for line in readfile('copying.md').split('\n'):
        match = re.match("^ - `([^`]+)`.*$", line)
        if not match:
            continue

        filename = match.group(1)
        listed_files.add(filename)

    # file listed, but has no 3rd-party header?
    for filename in sorted(listed_files - third_party_files):
        if has_ext(filename, EXTENSIONS_REQUIRING_LEGAL_HEADERS):
            yield (
                "third-party file listing issue",
                (f"{filename}\n\tlisted in copying.md, but has no "
                 "third-party license header."),
                None
            )

    # file has 3rd-party header, but is not listed?
    for filename in sorted(third_party_files - listed_files):
        yield (
            "third-party file listing issue",
            (f"{filename}\n\thas a third-party license header, but isn't "
             "listed in copying.md"),
            None
        )


================================================
FILE: buildsystem/codecompliance/modes.py
================================================
# Copyright 2016-2022 the openage authors. See copying.md for legal info.

"""
Checks the mode of all files and prevents executable source files.
"""

import re
import pathlib
import stat

from .util import findfiles, SHEBANG


SHEBANG_RE = re.compile("^" + SHEBANG)

EXTENSIONS_NO_X_BIT = {
    '.h', '.cpp', '.py', '.pyx', '.pxi', '.cmake', '.h.in',
    '.cpp.in', '.py.in', '.h.template', '.cpp.template',
    '.py.template', '.qml'
}

EXTENSIONS_SHEBANG_XBIT = {
    '.sh', '.py'
}


def check_mode(filename):
    """
    Test if the the file has no executable bit set.
    """

    path = pathlib.Path(filename)
    filemode = path.stat().st_mode

    x_ok = False

    if filemode & (stat.S_IXGRP | stat.S_IXOTH | stat.S_IXUSR):

        if path.suffix in EXTENSIONS_SHEBANG_XBIT:
            # if the file is allowed to have a shebang,
            # allow its executable bit if it actually has a shebang
            with path.open(encoding='utf-8') as file:
                firstline = file.readline()

                if SHEBANG_RE.match(firstline):
                    x_ok = True

        if not x_ok:
            raise ValueError(f'file {filename} is executable')


def find_issues(check_files, paths):
    """
    Check all source files for their required filesystem bits.
    """

    for filename in findfiles(paths, EXTENSIONS_NO_X_BIT):
        if check_files and filename not in check_files:
            continue

        try:
            check_mode(filename)
        except ValueError as exc:
            yield ("wrong file access bits", str(exc), None)
            continue


================================================
FILE: buildsystem/codecompliance/pylint.py
================================================
# Copyright 2015-2023 the openage authors. See copying.md for legal info.

"""
Checks the Python modules with pylint.
"""

from pylint import lint

from .pystyle import filter_file_list
from .util import findfiles


def find_pyx_modules(dirnames):
    """ Yields the names of all .pyx modules. """
    for pyx_file in findfiles(dirnames, [".pyx"]):
        yield pyx_file.replace('/', '.')[:-len(".pyx")]


def find_issues(check_files, dirnames):
    """ Invokes the external utility. """

    invocation = ['--rcfile=etc/pylintrc', '--reports=n']

    from multiprocessing import cpu_count
    invocation.append(f"--jobs={cpu_count():d}")

    if check_files is None:
        invocation.extend(dirnames)
    else:
        check_files = list(filter_file_list(check_files, dirnames))
        if not check_files:
            return
        invocation.extend(check_files)

    try:
        lint.Run(invocation)
    except SystemExit as exc:
        error_count = exc.args[0]
        if error_count != 0:
            if check_files is None:
                msg = f"python code is noncompliant: {error_count:d}"
            else:
                msg = ("false positives may result from not checking the "
                       "entire codebase")

            yield "linting issue", msg, None


================================================
FILE: buildsystem/codecompliance/pystyle.py
================================================
# Copyright 2014-2018 the openage authors. See copying.md for legal info.

"""
Checks PEP8 compliance, with some exceptions.
"""

try:
    from pycodestyle import StyleGuide
except ImportError:
    from pep8 import StyleGuide


# these errors will be ignored by pep8
IGNORE_ERRORS = (
    "E221",  # multiple spaces before operator
    "E241",  # multiple spaces after ','
    "E251",  # unexpected spaces around keyword / parameter equals
    "E501",  # line too long
)


def filter_file_list(check_files, dirnames):
    """
    Yields all those files in check_files that are in one of the directories
    and end in '.py'.
    """
    for filename in check_files:
        if not filename.endswith('.py'):
            continue

        if any(filename.startswith(dirname) for dirname in dirnames):
            yield filename


def find_issues(check_files, dirnames):
    """
    Finds all issues in the given directories (filtered by check_files).
    """
    checker = StyleGuide()
    checker.options.ignore = IGNORE_ERRORS

    filenames = dirnames
    if check_files is not None:
        filenames = filter_file_list(check_files, dirnames)

    report = checker.check_files(filenames)

    if report.messages:
        yield ("style issue", "python code violates pep8", None)


================================================
FILE: buildsystem/codecompliance/textfiles.py
================================================
# Copyright 2015-2019 the openage authors. See copying.md for legal info.

"""
Checks some general whitespace rules and the encoding for text files.
"""

import re

from .util import findfiles, readfile, has_ext, issue_str_line, BADUTF8FILES

TRAIL_WHITESPACE_RE = re.compile((
    # trailing whitespace
    r"( |\t)+\n"
))

IMMEDIATE_TODO_RE = re.compile(
    "as" + "df",
    re.IGNORECASE  # pylint: disable=no-member
)


def find_issues(dirnames, exts):
    """
    Checks all files ending in exts in dirnames.
    """
    for filename in findfiles(dirnames, exts):
        data = readfile(filename)
        analyse_each_line = False

        if filename.endswith('.gen.h') or filename.endswith('.gen.cpp'):
            # TODO all this for now, until someone fixes the codegen.
            continue

        if filename.startswith('openage/') and filename.endswith('.cpp'):
            # allow issues for Cython-generated files.
            continue

        if '\r\n' in data:
            yield "Windows EOL format", filename, None

        if data.endswith('\n\n'):
            yield "Trailing newline at file end", filename, None

        if data and not data.endswith('\n'):
            yield "File does not end in '\\n'", filename, None

        if has_ext(filename, ('.py', '.pyx', '.pxd')):
            if '\t' in data:
                yield "File contains tabs", filename, None

        if TRAIL_WHITESPACE_RE.search(data) or IMMEDIATE_TODO_RE.search(data):
            analyse_each_line = True

        # If there are possible issues, perform an in-depth analysis.
        if analyse_each_line:
            yield from find_issues_with_lines(filename)

    for filename in BADUTF8FILES:
        yield "Not valid UTF-8", filename


def find_issues_with_lines(filename):
    """
    Checks a file for issues per line.
    """
    data = readfile(filename)

    for num, line in enumerate(data.splitlines(True), start=1):

        match = TRAIL_WHITESPACE_RE.search(line)
        if match:
            yield issue_str_line("Trailing whitespace", filename, line, num,
                                 (match.start(1), match.end(1)))

        match = IMMEDIATE_TODO_RE.search(line)
        if match:
            yield issue_str_line("Found 'as"
                                 "df', indicating an immediate TODO",
                                 filename, line, num,
                                 (match.start(), match.end()))


================================================
FILE: buildsystem/codecompliance/util.py
================================================
# Copyright 2014-2023 the openage authors. See copying.md for legal info.

"""
Some utilities.
"""

import logging
import os


SHEBANG = "#!/.*\n(#?\n)?"

FILECACHE = {}
BADUTF8FILES = set()


def log_setup(setting, default=1):
    """
    Perform setup for the logger.
    Run before any logging.log thingy is called.

    if setting is 0: the default is used, which is WARNING.
    else: setting + default is used.
    """

    levels = (logging.ERROR, logging.WARNING, logging.INFO,
              logging.DEBUG, logging.NOTSET)

    factor = clamp(default + setting, 0, len(levels) - 1)
    level = levels[factor]

    logging.basicConfig(level=level, format="[%(asctime)s] %(message)s")
    logging.captureWarnings(True)


def clamp(number, smallest, largest):
    """ return number but limit it to the inclusive given value range """
    return max(smallest, min(number, largest))


class Strlazy:
    # pylint: disable=too-few-public-methods
    """
    to be used like this: logging.debug("rolf %s", strlazy(lambda: do_something()))
    so do_something is only called when the debug message is actually printed
    do_something could also be an f-string.
    """
    def __init__(self, fun):
        self.fun = fun

    def __str__(self):
        return self.fun()


def has_ext(fname, exts):
    """
    Returns true if fname ends in any of the extensions in ext.
    """
    for ext in exts:
        if ext == '':
            if os.path.splitext(fname)[1] == '':
                return True
        elif fname.endswith(ext):
            return True

    return False


def readfile(filename):
    """
    reads the file, and returns it as a str object.

    if the file has already been read in the past,
    returns it from the cache.
    """
    if filename not in FILECACHE:
        with open(filename, 'rb') as fileobj:
            data = fileobj.read()

        try:
            data = data.decode('utf-8')
        except UnicodeDecodeError:
            data = data.decode('utf-8', errors='replace')
            BADUTF8FILES.add(filename)

        FILECACHE[filename] = data

    return FILECACHE[filename]


def writefile(filename, new_content):
    """
    writes the file and update it in the cache.
    """
    if filename in BADUTF8FILES:
        raise ValueError(f"{filename}: cannot write due to utf8-errors.")

    with open(filename, 'w', encoding='utf8') as fileobj:
        fileobj.write(new_content)

    FILECACHE[filename] = new_content


def findfiles(paths, exts=None):
    """
    yields all files in paths with names ending in an ext from exts.

    If exts is None, all extensions are accepted.

    hidden dirs and files are ignored.
    """
    for path in paths:
        for filename in os.listdir(path):
            if filename.startswith('.'):
                continue

            filename = os.path.join(path, filename)

            if os.path.isdir(filename):
                yield from findfiles((filename,), exts)
                continue

            if exts is None or has_ext(filename, exts):
                yield filename


def issue_str(title, filename, fix=None):
    """
    Creates a formated (title, text) desciption of an issue.

    TODO use this function and issue_str_line for all issues, so the format
    can be easily changed (exta text, colors, etc)
    """
    return (title, filename, fix)


# gread hint, pylint. thank you so much.
# pylint: disable=too-many-arguments
def issue_str_line(title, filename, line, line_number, highlight, fix=None):
    """
    Creates a formated (title, text) desciption of an issue with information
    about the location in the file.
    line:        line content
    line_number: line id in the file
    highlight:   a tuple of (start, end), where
        start:   match start in the line
        end:     match end in the line
    """

    start, end = highlight
    start += 1
    line = line.replace("\n", "").replace("\t", " ")

    return (
        title,
        (
            filename + "\n"
            "\tline: " + str(line_number) + "\n"   # line number
            "\tat:   '" + line + "'\n"             # line content
            "\t      " + (' ' * start) +           # mark position with ^
            "\x1b[32;1m^" + ("~" * (end - start)) + "\x1b[m"
        ),
        fix
    )


================================================
FILE: buildsystem/codegen.cmake
================================================
# Copyright 2014-2025 the openage authors. See copying.md for legal info.

# set CODEGEN_SCU_FILE to the absolute path to SCU file
macro(get_codegen_scu_file)
	set(CODEGEN_SCU_FILE "${CMAKE_BINARY_DIR}/libopenage/codegen_scu.gen.cpp")
endmacro()

function(codegen_run)
	# this function must be called once all required assets have been created, but before the executable is finalized.

	# make sure this function gets called only once
	get_property(codegen_run GLOBAL PROPERTY SFT_CODEGEN_HAS_BEEN_RUN)
	if(codegen_run)
		message(FATAL_ERROR "codegen has already been run")
	endif()
	set_property(GLOBAL PROPERTY SFT_CODEGEN_HAS_BEEN_RUN 1)

	set(CODEGEN_INVOCATION
		"${PYTHON}" -m openage codegen
		"--input-dir=${CMAKE_SOURCE_DIR}"
		"--output-dir=${CMAKE_BINARY_DIR}"
		"--generated-list-file=${CMAKE_BINARY_DIR}/codegen_generated_files"
		"--depend-list-file=${CMAKE_BINARY_DIR}/codegen_depends")

	execute_process(COMMAND
		${CODEGEN_INVOCATION} --mode=dryrun
		WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
		RESULT_VARIABLE COMMAND_RESULT
	)

	if(NOT ${COMMAND_RESULT} EQUAL 0)
		message(FATAL_ERROR "failed to get target list from codegen invocation")
	endif()

	FILE(READ "${CMAKE_BINARY_DIR}/codegen_generated_files" CODEGEN_TARGET_FILES)
	FILE(READ "${CMAKE_BINARY_DIR}/codegen_depends" CODEGEN_DEPENDS)
	STRING(REGEX REPLACE "\n" ";" CODEGEN_TARGET_FILES ${CODEGEN_TARGET_FILES})
	STRING(REGEX REPLACE "\n" ";" CODEGEN_DEPENDS ${CODEGEN_DEPENDS})

	# as the codegen creates all files at once,
	# let the buildsystem only depend on this single dummy file.
	# otherwise the codegen invocation would be done for each generated source.
	set(CODEGEN_TIMEFILE "${CMAKE_BINARY_DIR}/codegen_timefile")

	add_custom_command(
		OUTPUT "${CODEGEN_TIMEFILE}"
		BYPRODUCTS ${CODEGEN_TARGET_FILES}
		COMMAND ${CODEGEN_INVOCATION} --mode=codegen "--touch-file-on-cache-change=${CMAKE_CURRENT_LIST_FILE}" --force-rerun-on-generated-list-change
		COMMAND "${CMAKE_COMMAND}" -E touch "${CODEGEN_TIMEFILE}"
		WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
		DEPENDS ${CODEGEN_DEPENDS}
		COMMENT "openage.codegen: generating c++ code"
	)

	add_custom_target(cppgen
		DEPENDS "${CODEGEN_TIMEFILE}"
	)

	add_custom_target(cleancodegen
		COMMAND ${CODEGEN_INVOCATION} --mode=clean
		COMMAND "${CMAKE_COMMAND}" -E remove "${CODEGEN_TIMEFILE}"
		WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
	)

	get_codegen_scu_file()
	get_filename_component(CODEGEN_SCU_DIR ${CODEGEN_SCU_FILE} DIRECTORY)

	set(CODEGEN_SCU_CONTENT "// Generated by codegen.\n\n")
	list(SORT CODEGEN_TARGET_FILES)
	foreach(target ${CODEGEN_TARGET_FILES})
		if("${target}" MATCHES "\\.cpp$")
			file(RELATIVE_PATH target_rel ${CODEGEN_SCU_DIR} ${target})
			string(APPEND CODEGEN_SCU_CONTENT "#include \"${target_rel}\"\n")
		endif()
	endforeach()

	write_on_change(${CODEGEN_SCU_FILE} "${CODEGEN_SCU_CONTENT}")
endfunction()


================================================
FILE: buildsystem/compilepy.py
================================================
# Copyright 2015-2022 the openage authors. See copying.md for legal info.

"""
Compiles python modules with cpython to pyc/pyo files.
"""

import argparse
import importlib.util
import os
import py_compile
import shutil
import sys


def clone_file_to_dir(sourcefile, input_dir, output_dir):
    """
    Make a copy of sourcefile from input_dir to output_dir
    Try hardlinking first; on failure fallback to copy.
    Caveat: source files already in output_dir are not cloned.

    :return: the path of file created in output_dir
    """
    if os.path.samefile(input_dir, output_dir) or sourcefile.startswith(output_dir):
        return sourcefile

    relsrcpath = os.path.relpath(sourcefile, input_dir)
    targetfile = os.path.join(output_dir, relsrcpath)

    if os.path.exists(targetfile) and os.path.samefile(sourcefile, targetfile):
        return targetfile

    os.makedirs(os.path.dirname(targetfile), exist_ok=True)

    # try to hardlink
    try:
        os.link(sourcefile, targetfile)
        return targetfile
    except OSError:
        pass

    # we don't try to symlink, because then Python may "intelligently"
    # determine the actual location, and refuse to work.

    # fallback to copying the file
    shutil.copy(sourcefile, targetfile)

    return targetfile


def main():
    """ CLI entry point """
    cli = argparse.ArgumentParser()
    cli.add_argument("pymodule_list_file", help=(
        "semicolon-separated list of all modules that shall be compiled"
    ))
    cli.add_argument("input_dir", help=(
        "base directory where files from the above list are in."
    ))
    cli.add_argument("output_dir", help=(
        "base directory where output files will be created."
    ))
    cli.add_argument("--print-output-paths-only", action="store_true", help=(
        "print the paths of the compiled output files and exit"
    ))
    args = cli.parse_args()

    with open(args.pymodule_list_file, encoding='utf8') as fileobj:
        modules = fileobj.read().strip().split(';')
        if modules == ['']:
            modules = []

    if not os.path.isdir(args.output_dir):
        cli.error(f"not a directory: '{args.output_dir}'")

    all_output_files = []
    to_compile = []

    for module in modules:
        # th
Download .txt
gitextract_3ogk531m/

├── .clang-format
├── .github/
│   ├── PULL_REQUEST_TEMPLATES/
│   │   ├── pull_request_template.md
│   │   └── release_template.md
│   └── workflows/
│       ├── macosx-ci.yml
│       ├── ubuntu-24.04.yml
│       ├── windows-server-2019.yml
│       └── windows-server-2022.yml
├── .gitignore
├── .mailmap
├── CMakeLists.txt
├── Makefile
├── README.md
├── assets/
│   ├── .gitignore
│   ├── CMakeLists.txt
│   ├── logo/
│   │   └── CMakeLists.txt
│   ├── qml/
│   │   ├── .gitignore
│   │   ├── Actions.qml
│   │   ├── ActionsGrid.qml
│   │   ├── BindsHelp.qml
│   │   ├── ButtonExtruded.qml
│   │   ├── ButtonExtrudedStyle.qml
│   │   ├── ButtonFlat.qml
│   │   ├── ButtonFlatStyle.qml
│   │   ├── CheckBoxFlat.qml
│   │   ├── CheckBoxFlatStyle.qml
│   │   ├── CreateGameWhenReady.qml
│   │   ├── GeneratorControl.qml
│   │   ├── GeneratorParametersConfiguration.qml
│   │   ├── IngameHud.qml
│   │   ├── Paper.qml
│   │   ├── TextFieldFlat.qml
│   │   ├── TextFieldFlatStyle.qml
│   │   ├── TypePicker.qml
│   │   └── main.qml
│   ├── shaders/
│   │   ├── CMakeLists.txt
│   │   ├── alphamask.frag.glsl
│   │   ├── alphamask.vert.glsl
│   │   ├── equalsEpsilon.glsl
│   │   ├── final.frag.glsl
│   │   ├── final.vert.glsl
│   │   ├── hud_drag_select.frag.glsl
│   │   ├── hud_drag_select.vert.glsl
│   │   ├── identity.vert.glsl
│   │   ├── maptexture.frag.glsl
│   │   ├── maptexture.vert.glsl
│   │   ├── skybox.frag.glsl
│   │   ├── skybox.vert.glsl
│   │   ├── teamcolors.frag.glsl
│   │   ├── terrain.frag.glsl
│   │   ├── terrain.vert.glsl
│   │   ├── texturefont.frag.glsl
│   │   ├── texturefont.vert.glsl
│   │   ├── world2d.frag.glsl
│   │   ├── world2d.vert.glsl
│   │   └── world3d.vert.glsl
│   ├── test/
│   │   ├── CMakeLists.txt
│   │   ├── nyan/
│   │   │   ├── CMakeLists.txt
│   │   │   └── pong.nyan
│   │   ├── qml/
│   │   │   ├── CMakeLists.txt
│   │   │   └── main.qml
│   │   ├── shaders/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── demo_0_display.frag.glsl
│   │   │   ├── demo_0_display.vert.glsl
│   │   │   ├── demo_1_display.frag.glsl
│   │   │   ├── demo_1_display.vert.glsl
│   │   │   ├── demo_1_obj.frag.glsl
│   │   │   ├── demo_1_obj.vert.glsl
│   │   │   ├── demo_2_display.frag.glsl
│   │   │   ├── demo_2_display.vert.glsl
│   │   │   ├── demo_2_obj.frag.glsl
│   │   │   ├── demo_2_obj.vert.glsl
│   │   │   ├── demo_4_display.frag.glsl
│   │   │   ├── demo_4_display.vert.glsl
│   │   │   ├── demo_4_obj.frag.glsl
│   │   │   ├── demo_4_obj.vert.glsl
│   │   │   ├── demo_5_obj.frag.glsl
│   │   │   ├── demo_5_obj.vert.glsl
│   │   │   ├── demo_6_2d.frag.glsl
│   │   │   ├── demo_6_2d.vert.glsl
│   │   │   ├── demo_6_2d_frame.frag.glsl
│   │   │   ├── demo_6_2d_frame.vert.glsl
│   │   │   ├── demo_6_2d_frustum_frame.vert.glsl
│   │   │   ├── demo_6_3d.frag.glsl
│   │   │   ├── demo_6_3d.vert.glsl
│   │   │   ├── demo_6_display.frag.glsl
│   │   │   ├── demo_6_display.vert.glsl
│   │   │   ├── demo_7_shader_command.frag.glsl
│   │   │   ├── demo_7_shader_command.vert.glsl
│   │   │   ├── demo_7_snippets/
│   │   │   │   ├── alpha.snippet
│   │   │   │   └── color.snippet
│   │   │   └── pathfinding/
│   │   │       ├── CMakeLists.txt
│   │   │       ├── demo_0_cost_field.frag.glsl
│   │   │       ├── demo_0_cost_field.vert.glsl
│   │   │       ├── demo_0_display.frag.glsl
│   │   │       ├── demo_0_display.vert.glsl
│   │   │       ├── demo_0_flow_field.frag.glsl
│   │   │       ├── demo_0_flow_field.vert.glsl
│   │   │       ├── demo_0_grid.frag.glsl
│   │   │       ├── demo_0_grid.vert.glsl
│   │   │       ├── demo_0_integration_field.frag.glsl
│   │   │       ├── demo_0_integration_field.vert.glsl
│   │   │       ├── demo_0_obj.frag.glsl
│   │   │       ├── demo_0_obj.vert.glsl
│   │   │       ├── demo_0_vector.frag.glsl
│   │   │       ├── demo_0_vector.vert.glsl
│   │   │       ├── demo_1_display.frag.glsl
│   │   │       ├── demo_1_display.vert.glsl
│   │   │       ├── demo_1_grid.frag.glsl
│   │   │       ├── demo_1_grid.vert.glsl
│   │   │       ├── demo_1_obj.frag.glsl
│   │   │       └── demo_1_obj.vert.glsl
│   │   └── textures/
│   │       ├── CMakeLists.txt
│   │       ├── test_animation.sprite
│   │       ├── test_gaben.sprite
│   │       ├── test_gaben.texture
│   │       ├── test_missing.sprite
│   │       ├── test_missing.texture
│   │       ├── test_tank.sprite
│   │       ├── test_tank.texture
│   │       ├── test_tank_mirrored.sprite
│   │       ├── test_terrain.terrain
│   │       ├── test_terrain.texture
│   │       ├── test_terrain2.terrain
│   │       ├── test_terrain2.texture
│   │       └── test_texture.texture
│   └── textures/
│       ├── CMakeLists.txt
│       └── torn_paper_edge.docx
├── buildsystem/
│   ├── CheckCompilerFeatures.cmake
│   ├── CheckInSourceBuild.cmake
│   ├── CheckRuntimeDependencies.cmake
│   ├── DependencyFetch.cmake
│   ├── DetectProjectVersion.cmake
│   ├── HandleCXXOptions.cmake
│   ├── HandlePythonOptions.cmake
│   ├── __init__.py
│   ├── check_py_file_list.py
│   ├── codecompliance/
│   │   ├── __init__.py
│   │   ├── __main__.py
│   │   ├── authors.py
│   │   ├── clangtidy.py
│   │   ├── cppstyle.py
│   │   ├── cython.py
│   │   ├── headerguards.py
│   │   ├── legal.py
│   │   ├── modes.py
│   │   ├── pylint.py
│   │   ├── pystyle.py
│   │   ├── textfiles.py
│   │   └── util.py
│   ├── codegen.cmake
│   ├── compilepy.py
│   ├── cpp.cmake
│   ├── cythonize.py
│   ├── doxygen.cmake
│   ├── doxygen_custom.css
│   ├── inplacemodules.py
│   ├── modules/
│   │   ├── DownloadCache.cmake
│   │   ├── FindCython.cmake
│   │   ├── FindEpoxy.cmake
│   │   ├── FindGCCBacktrace.cmake
│   │   ├── FindGPerfTools.cmake
│   │   ├── FindHarfBuzz.cmake
│   │   ├── FindInotify.cmake
│   │   ├── FindOgg.cmake
│   │   ├── FindOpusfile.cmake
│   │   ├── FindPython.cmake
│   │   └── FindPython_test.cpp
│   ├── options.cmake
│   ├── pxdgen.py
│   ├── python.cmake
│   ├── scripts/
│   │   ├── EmbedFont.cmake
│   │   ├── EmbedPython.cmake
│   │   ├── EmbedWinDependencies.cmake
│   │   └── copy_modules.py
│   ├── templates/
│   │   ├── Doxyfile.in
│   │   ├── ExternalFetch.cmake.in
│   │   ├── ForwardVariables.cmake.in
│   │   ├── openage.bat.in
│   │   └── qt.conf
│   └── util.cmake
├── cfg/
│   ├── .gitignore
│   ├── CMakeLists.txt
│   ├── converter/
│   │   └── games/
│   │       ├── aoc/
│   │       │   └── version_hashes.toml
│   │       ├── aoc_demo/
│   │       │   └── version_hashes.toml
│   │       ├── aok/
│   │       │   └── version_hashes.toml
│   │       ├── de1/
│   │       │   └── version_hashes.toml
│   │       ├── de2/
│   │       │   └── version_hashes.toml
│   │       ├── game_editions.toml
│   │       ├── game_expansions.toml
│   │       ├── hd/
│   │       │   └── version_hashes.toml
│   │       ├── hd_ak/
│   │       │   └── version_hashes.toml
│   │       ├── hd_fgt/
│   │       │   └── version_hashes.toml
│   │       ├── hd_raj/
│   │       │   └── version_hashes.toml
│   │       ├── ror/
│   │       │   └── version_hashes.toml
│   │       ├── swgb/
│   │       │   └── version_hashes.toml
│   │       └── swgb_cc/
│   │           └── version_hashes.toml
│   └── keybinds.oac
├── changelog.md
├── configure
├── copying.md
├── dist/
│   ├── CMakeLists.txt
│   ├── README.md
│   └── openage.desktop
├── doc/
│   ├── README.md
│   ├── assets.md
│   ├── build_instructions/
│   │   ├── arch_linux.md
│   │   ├── debian.md
│   │   ├── docker.md
│   │   ├── fedora.md
│   │   ├── freebsd.md
│   │   ├── gentoo.md
│   │   ├── macos.md
│   │   ├── nix.md
│   │   ├── opensuse.md
│   │   ├── ubuntu.md
│   │   └── windows_msvc.md
│   ├── building.md
│   ├── buildsystem.md
│   ├── changelogs/
│   │   ├── engine/
│   │   │   ├── v0.0.0.md
│   │   │   ├── v0.1.0.md
│   │   │   ├── v0.2.0.md
│   │   │   ├── v0.2.1.md
│   │   │   ├── v0.2.2.md
│   │   │   ├── v0.2.3.md
│   │   │   ├── v0.3.0-alpha.md
│   │   │   ├── v0.3.0.md
│   │   │   ├── v0.4.0.md
│   │   │   ├── v0.4.1.md
│   │   │   ├── v0.5.0.md
│   │   │   ├── v0.5.1.md
│   │   │   ├── v0.5.2.md
│   │   │   ├── v0.5.3.md
│   │   │   └── v0.6.0.md
│   │   └── nyan_api/
│   │       ├── v0.1.0.md
│   │       ├── v0.2.0.md
│   │       ├── v0.3.0.md
│   │       ├── v0.4.0.md
│   │       ├── v0.4.1.md
│   │       ├── v0.5.0.md
│   │       └── v0.6.0.md
│   ├── code/
│   │   ├── README.md
│   │   ├── architecture.md
│   │   ├── converter/
│   │   │   ├── README.md
│   │   │   ├── architecture_overview.md
│   │   │   └── workflow.md
│   │   ├── coordinate-systems.md
│   │   ├── curves.md
│   │   ├── event_system.md
│   │   ├── exceptions.md
│   │   ├── game_simulation/
│   │   │   ├── README.md
│   │   │   ├── activity.md
│   │   │   ├── components.md
│   │   │   ├── game_entity.md
│   │   │   └── systems.md
│   │   ├── gui.md
│   │   ├── images/
│   │   │   ├── component_classes.uxf
│   │   │   ├── continuous_curve.ggb
│   │   │   ├── curves_classes.uxf
│   │   │   ├── discrete_curve.ggb
│   │   │   ├── engine_architecture.uxf
│   │   │   ├── event_classes.uxf
│   │   │   ├── game_entity_classes.uxf
│   │   │   ├── pathfinder_architecture.uxf
│   │   │   ├── segmented_curve.ggb
│   │   │   ├── simulation.uxf
│   │   │   ├── system_classes.uxf
│   │   │   └── time_classes.uxf
│   │   ├── input/
│   │   │   └── README.md
│   │   ├── logger.md
│   │   ├── optimization.md
│   │   ├── pathfinding/
│   │   │   ├── README.md
│   │   │   └── field_types.md
│   │   ├── pyinterface.md
│   │   ├── renderer/
│   │   │   ├── README.md
│   │   │   ├── demos.md
│   │   │   ├── level1.md
│   │   │   └── level2.md
│   │   ├── testing.md
│   │   └── time.md
│   ├── contributing.md
│   ├── convert/
│   │   ├── README.md
│   │   ├── convert_single_file.md
│   │   ├── debugger.md
│   │   ├── interactive.md
│   │   └── nyan.md
│   ├── debug.md
│   ├── development.md
│   ├── ide/
│   │   ├── README.md
│   │   ├── configs/
│   │   │   └── vscode/
│   │   │       └── tasks.json
│   │   ├── emacs.md
│   │   ├── qt_creator.md
│   │   └── vscode.md
│   ├── ideas/
│   │   ├── ai.md
│   │   ├── editor/
│   │   │   ├── README.md
│   │   │   ├── campaigns.md
│   │   │   ├── economy.md
│   │   │   ├── multiplayer.md
│   │   │   ├── scripting.md
│   │   │   ├── tech.md
│   │   │   ├── terrain-ui.txt
│   │   │   ├── terrain.md
│   │   │   └── units.md
│   │   ├── fr_technical_overview.md
│   │   ├── gameplay.md
│   │   ├── interface.md
│   │   └── technical.md
│   ├── media/
│   │   ├── aoc-slp-list.md
│   │   ├── blendomatic.md
│   │   ├── drs-files.md
│   │   ├── evolution-openage-gource.md
│   │   ├── filtermaps-dat.md
│   │   ├── lzx_compression_info.md
│   │   ├── openage/
│   │   │   ├── blendmask_format_spec.md
│   │   │   ├── blendtable_format_spec.md
│   │   │   ├── file_referencing.md
│   │   │   ├── modpack_definition_file.md
│   │   │   ├── modpacks.md
│   │   │   ├── palette_format_spec.md
│   │   │   ├── sprite_format_spec.md
│   │   │   ├── terrain_format_spec.md
│   │   │   └── texture_format_spec.md
│   │   ├── original-metadata.md
│   │   ├── patterns/
│   │   │   ├── sld.hexpat
│   │   │   ├── slp.hexpat
│   │   │   └── slp_v4.hexpat
│   │   ├── sld-files.md
│   │   ├── slp-files.md
│   │   ├── smp-files.md
│   │   ├── smx-files.md
│   │   ├── sound.md
│   │   ├── stemplet-dat.md
│   │   └── terrain.md
│   ├── media_convert.md
│   ├── nyan/
│   │   ├── README.md
│   │   ├── aoe2_nyan_tree.uxf
│   │   ├── api_reference/
│   │   │   ├── reference_ability.md
│   │   │   ├── reference_effect.md
│   │   │   ├── reference_modifier.md
│   │   │   ├── reference_resistance.md
│   │   │   ├── reference_root.md
│   │   │   └── reference_util.md
│   │   └── openage-lib.md
│   ├── project_structure.md
│   ├── releasing.md
│   ├── reverse_engineering/
│   │   ├── aoc_structures_00_09_26_0809
│   │   ├── civilizations.md
│   │   ├── game_mechanics/
│   │   │   ├── accuracy.md
│   │   │   ├── attacking_alarm.md
│   │   │   ├── build_speed.md
│   │   │   ├── building_placement.md
│   │   │   ├── damage.md
│   │   │   ├── formations.md
│   │   │   ├── garrison.md
│   │   │   ├── market.md
│   │   │   ├── monk_conversion.md
│   │   │   ├── pathfinding.md
│   │   │   ├── ram_speed.md
│   │   │   ├── rates.md
│   │   │   ├── repair.md
│   │   │   ├── research.md
│   │   │   ├── selection.md
│   │   │   ├── swgb/
│   │   │   │   ├── power.md
│   │   │   │   ├── shields.md
│   │   │   │   ├── stealth.md
│   │   │   │   └── user-interface.md
│   │   │   ├── switching_villager_tasks.md
│   │   │   ├── town_bell.md
│   │   │   ├── waypoints.md
│   │   │   └── wolves.md
│   │   ├── networking/
│   │   │   ├── 01-general.md
│   │   │   ├── 02-header.md
│   │   │   ├── 03-sync.md
│   │   │   ├── 04-lobby.md
│   │   │   ├── 05-chat_protocol.md
│   │   │   ├── 06-chat_message_spoofing.md
│   │   │   ├── 07-primary_action.md
│   │   │   ├── 08-movement.md
│   │   │   ├── 09-formation.md
│   │   │   ├── 10-unit_creation.md
│   │   │   ├── 11-buildings.md
│   │   │   ├── 12-market.md
│   │   │   ├── 13-other.md
│   │   │   ├── 14-ai.md
│   │   │   ├── 15-c-structs.md
│   │   │   └── technology_ids.md
│   │   ├── scoring.md
│   │   └── unit_stats/
│   │       ├── unit_stats.md
│   │       ├── unit_stats_afr.csv
│   │       ├── unit_stats_aoc.csv
│   │       ├── unit_stats_aoe.csv
│   │       ├── unit_stats_aoe.txt
│   │       ├── unit_stats_aok.csv
│   │       └── unit_stats_fe.csv
│   ├── running.md
│   └── troubleshooting.md
├── etc/
│   ├── gdb_pretty/
│   │   ├── __init__.py
│   │   └── printers.py
│   ├── lsan.supp
│   ├── openage.gdbinit
│   ├── pylintrc
│   └── valgrind-python.supp
├── flake.nix
├── kevinfile
├── legal/
│   ├── BSD-3-clause
│   ├── GPLv3
│   └── LGPLv2.0
├── libopenage/
│   ├── .gitignore
│   ├── CMakeLists.txt
│   ├── assets/
│   │   ├── CMakeLists.txt
│   │   ├── mod_manager.cpp
│   │   ├── mod_manager.h
│   │   ├── modpack.cpp
│   │   └── modpack.h
│   ├── audio/
│   │   ├── CMakeLists.txt
│   │   ├── audio_manager.cpp
│   │   ├── audio_manager.h
│   │   ├── category.cpp
│   │   ├── category.h
│   │   ├── dynamic_loader.cpp
│   │   ├── dynamic_loader.h
│   │   ├── dynamic_resource.cpp
│   │   ├── dynamic_resource.h
│   │   ├── error.cpp
│   │   ├── error.h
│   │   ├── format.cpp
│   │   ├── format.h
│   │   ├── hash_functions.h
│   │   ├── in_memory_loader.cpp
│   │   ├── in_memory_loader.h
│   │   ├── in_memory_resource.cpp
│   │   ├── in_memory_resource.h
│   │   ├── loader_policy.cpp
│   │   ├── loader_policy.h
│   │   ├── opus_dynamic_loader.cpp
│   │   ├── opus_dynamic_loader.h
│   │   ├── opus_in_memory_loader.cpp
│   │   ├── opus_in_memory_loader.h
│   │   ├── opus_loading.cpp
│   │   ├── opus_loading.h
│   │   ├── resource.cpp
│   │   ├── resource.h
│   │   ├── resource_def.cpp
│   │   ├── resource_def.h
│   │   ├── sound.cpp
│   │   ├── sound.h
│   │   └── types.h
│   ├── config.cpp.in
│   ├── config.h.in
│   ├── console/
│   │   ├── CMakeLists.txt
│   │   ├── buf.cpp
│   │   ├── buf.h
│   │   ├── console.cpp
│   │   ├── console.h
│   │   ├── draw.cpp
│   │   ├── draw.h
│   │   └── tests.cpp
│   ├── coord/
│   │   ├── CMakeLists.txt
│   │   ├── chunk.cpp
│   │   ├── chunk.h
│   │   ├── coord.cpp.template
│   │   ├── coord.h.template
│   │   ├── coord_test.cpp
│   │   ├── declarations.cpp
│   │   ├── declarations.h
│   │   ├── phys.cpp
│   │   ├── phys.h
│   │   ├── pixel.cpp
│   │   ├── pixel.h
│   │   ├── scene.cpp
│   │   ├── scene.h
│   │   ├── term.cpp
│   │   ├── term.h
│   │   ├── tile.cpp
│   │   └── tile.h
│   ├── curve/
│   │   ├── CMakeLists.txt
│   │   ├── base_curve.cpp
│   │   ├── base_curve.h
│   │   ├── container/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── array.cpp
│   │   │   ├── array.h
│   │   │   ├── element_wrapper.cpp
│   │   │   ├── element_wrapper.h
│   │   │   ├── iterator.cpp
│   │   │   ├── iterator.h
│   │   │   ├── map.cpp
│   │   │   ├── map.h
│   │   │   ├── map_filter_iterator.cpp
│   │   │   ├── map_filter_iterator.h
│   │   │   ├── queue.cpp
│   │   │   ├── queue.h
│   │   │   ├── queue_filter_iterator.cpp
│   │   │   └── queue_filter_iterator.h
│   │   ├── continuous.cpp
│   │   ├── continuous.h
│   │   ├── discrete.cpp
│   │   ├── discrete.h
│   │   ├── discrete_mod.cpp
│   │   ├── discrete_mod.h
│   │   ├── interpolated.cpp
│   │   ├── interpolated.h
│   │   ├── keyframe.cpp
│   │   ├── keyframe.h
│   │   ├── keyframe_container.cpp
│   │   ├── keyframe_container.h
│   │   ├── segmented.cpp
│   │   ├── segmented.h
│   │   └── tests/
│   │       ├── CMakeLists.txt
│   │       ├── container.cpp
│   │       └── curve_types.cpp
│   ├── cvar/
│   │   ├── CMakeLists.txt
│   │   ├── cvar.cpp
│   │   └── cvar.h
│   ├── datastructure/
│   │   ├── CMakeLists.txt
│   │   ├── concurrent_queue.h
│   │   ├── constexpr_map.h
│   │   ├── pairing_heap.h
│   │   ├── tests.cpp
│   │   └── tests.h
│   ├── engine/
│   │   ├── CMakeLists.txt
│   │   ├── engine.cpp
│   │   └── engine.h
│   ├── error/
│   │   ├── CMakeLists.txt
│   │   ├── backtrace.cpp
│   │   ├── backtrace.h
│   │   ├── demo.cpp
│   │   ├── error.cpp
│   │   ├── error.h
│   │   ├── handlers.cpp
│   │   ├── handlers.h
│   │   ├── stackanalyzer.cpp
│   │   └── stackanalyzer.h
│   ├── event/
│   │   ├── CMakeLists.txt
│   │   ├── demo/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── aicontroller.cpp
│   │   │   ├── aicontroller.h
│   │   │   ├── gamestate.cpp
│   │   │   ├── gamestate.h
│   │   │   ├── gui.cpp
│   │   │   ├── gui.h
│   │   │   ├── main.cpp
│   │   │   ├── main.h
│   │   │   ├── physics.cpp
│   │   │   └── physics.h
│   │   ├── event.cpp
│   │   ├── event.h
│   │   ├── event_loop.cpp
│   │   ├── event_loop.h
│   │   ├── evententity.cpp
│   │   ├── evententity.h
│   │   ├── eventhandler.cpp
│   │   ├── eventhandler.h
│   │   ├── eventqueue.cpp
│   │   ├── eventqueue.h
│   │   ├── eventstore.cpp
│   │   ├── eventstore.h
│   │   ├── state.cpp
│   │   ├── state.h
│   │   └── tests.cpp
│   ├── gamestate/
│   │   ├── CMakeLists.txt
│   │   ├── activity/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── activity.cpp
│   │   │   ├── activity.h
│   │   │   ├── condition/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── command_in_queue.cpp
│   │   │   │   ├── command_in_queue.h
│   │   │   │   ├── next_command.cpp
│   │   │   │   └── next_command.h
│   │   │   ├── end_node.cpp
│   │   │   ├── end_node.h
│   │   │   ├── event/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── command_in_queue.cpp
│   │   │   │   ├── command_in_queue.h
│   │   │   │   ├── wait.cpp
│   │   │   │   └── wait.h
│   │   │   ├── node.cpp
│   │   │   ├── node.h
│   │   │   ├── start_node.cpp
│   │   │   ├── start_node.h
│   │   │   ├── task_node.cpp
│   │   │   ├── task_node.h
│   │   │   ├── task_system_node.cpp
│   │   │   ├── task_system_node.h
│   │   │   ├── tests.cpp
│   │   │   ├── types.cpp
│   │   │   ├── types.h
│   │   │   ├── xor_event_gate.cpp
│   │   │   ├── xor_event_gate.h
│   │   │   ├── xor_gate.cpp
│   │   │   └── xor_gate.h
│   │   ├── api/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── ability.cpp
│   │   │   ├── ability.h
│   │   │   ├── activity.cpp
│   │   │   ├── activity.h
│   │   │   ├── animation.cpp
│   │   │   ├── animation.h
│   │   │   ├── definitions.cpp
│   │   │   ├── definitions.h
│   │   │   ├── patch.cpp
│   │   │   ├── patch.h
│   │   │   ├── player_setup.cpp
│   │   │   ├── player_setup.h
│   │   │   ├── property.cpp
│   │   │   ├── property.h
│   │   │   ├── sound.cpp
│   │   │   ├── sound.h
│   │   │   ├── terrain.cpp
│   │   │   ├── terrain.h
│   │   │   ├── types.cpp
│   │   │   ├── types.h
│   │   │   ├── util.cpp
│   │   │   └── util.h
│   │   ├── component/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── api/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── idle.cpp
│   │   │   │   ├── idle.h
│   │   │   │   ├── live.cpp
│   │   │   │   ├── live.h
│   │   │   │   ├── move.cpp
│   │   │   │   ├── move.h
│   │   │   │   ├── selectable.cpp
│   │   │   │   ├── selectable.h
│   │   │   │   ├── turn.cpp
│   │   │   │   └── turn.h
│   │   │   ├── api_component.cpp
│   │   │   ├── api_component.h
│   │   │   ├── base_component.cpp
│   │   │   ├── base_component.h
│   │   │   ├── internal/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── activity.cpp
│   │   │   │   ├── activity.h
│   │   │   │   ├── command_queue.cpp
│   │   │   │   ├── command_queue.h
│   │   │   │   ├── commands/
│   │   │   │   │   ├── CMakeLists.txt
│   │   │   │   │   ├── base_command.cpp
│   │   │   │   │   ├── base_command.h
│   │   │   │   │   ├── custom.cpp
│   │   │   │   │   ├── custom.h
│   │   │   │   │   ├── idle.cpp
│   │   │   │   │   ├── idle.h
│   │   │   │   │   ├── move.cpp
│   │   │   │   │   ├── move.h
│   │   │   │   │   ├── types.cpp
│   │   │   │   │   └── types.h
│   │   │   │   ├── ownership.cpp
│   │   │   │   ├── ownership.h
│   │   │   │   ├── position.cpp
│   │   │   │   └── position.h
│   │   │   ├── internal_component.cpp
│   │   │   ├── internal_component.h
│   │   │   ├── types.cpp
│   │   │   └── types.h
│   │   ├── definitions.cpp
│   │   ├── definitions.h
│   │   ├── demo/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── demo_0.cpp
│   │   │   ├── demo_0.h
│   │   │   ├── tests.cpp
│   │   │   └── tests.h
│   │   ├── entity_factory.cpp
│   │   ├── entity_factory.h
│   │   ├── event/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── drag_select.cpp
│   │   │   ├── drag_select.h
│   │   │   ├── process_command.cpp
│   │   │   ├── process_command.h
│   │   │   ├── send_command.cpp
│   │   │   ├── send_command.h
│   │   │   ├── spawn_entity.cpp
│   │   │   ├── spawn_entity.h
│   │   │   ├── wait.cpp
│   │   │   └── wait.h
│   │   ├── game.cpp
│   │   ├── game.h
│   │   ├── game_entity.cpp
│   │   ├── game_entity.h
│   │   ├── game_state.cpp
│   │   ├── game_state.h
│   │   ├── manager.cpp
│   │   ├── manager.h
│   │   ├── map.cpp
│   │   ├── map.h
│   │   ├── player.cpp
│   │   ├── player.h
│   │   ├── simulation.cpp
│   │   ├── simulation.h
│   │   ├── system/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── activity.cpp
│   │   │   ├── activity.h
│   │   │   ├── idle.cpp
│   │   │   ├── idle.h
│   │   │   ├── move.cpp
│   │   │   ├── move.h
│   │   │   ├── types.cpp
│   │   │   └── types.h
│   │   ├── terrain.cpp
│   │   ├── terrain.h
│   │   ├── terrain_chunk.cpp
│   │   ├── terrain_chunk.h
│   │   ├── terrain_factory.cpp
│   │   ├── terrain_factory.h
│   │   ├── terrain_tile.cpp
│   │   ├── terrain_tile.h
│   │   ├── types.cpp
│   │   ├── types.h
│   │   ├── universe.cpp
│   │   ├── universe.h
│   │   ├── world.cpp
│   │   └── world.h
│   ├── input/
│   │   ├── CMakeLists.txt
│   │   ├── action.cpp
│   │   ├── action.h
│   │   ├── controller/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── camera/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── binding.cpp
│   │   │   │   ├── binding.h
│   │   │   │   ├── binding_context.cpp
│   │   │   │   ├── binding_context.h
│   │   │   │   ├── controller.cpp
│   │   │   │   └── controller.h
│   │   │   ├── game/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── binding.cpp
│   │   │   │   ├── binding.h
│   │   │   │   ├── binding_context.cpp
│   │   │   │   ├── binding_context.h
│   │   │   │   ├── controller.cpp
│   │   │   │   └── controller.h
│   │   │   └── hud/
│   │   │       ├── CMakeLists.txt
│   │   │       ├── binding.cpp
│   │   │       ├── binding.h
│   │   │       ├── binding_context.cpp
│   │   │       ├── binding_context.h
│   │   │       ├── controller.cpp
│   │   │       └── controller.h
│   │   ├── event.cpp
│   │   ├── event.h
│   │   ├── input_context.cpp
│   │   ├── input_context.h
│   │   ├── input_manager.cpp
│   │   ├── input_manager.h
│   │   ├── tests.cpp
│   │   ├── text_to_event.cpp
│   │   └── text_to_event.h
│   ├── job/
│   │   ├── CMakeLists.txt
│   │   ├── abortable_job_state.h
│   │   ├── job.h
│   │   ├── job_aborted_exception.h
│   │   ├── job_group.cpp
│   │   ├── job_group.h
│   │   ├── job_manager.cpp
│   │   ├── job_manager.h
│   │   ├── job_state.h
│   │   ├── job_state_base.h
│   │   ├── tests.cpp
│   │   ├── typed_job_state_base.h
│   │   ├── types.h
│   │   ├── worker.cpp
│   │   └── worker.h
│   ├── log/
│   │   ├── CMakeLists.txt
│   │   ├── file_logsink.cpp
│   │   ├── file_logsink.h
│   │   ├── level.cpp
│   │   ├── level.h
│   │   ├── log.cpp
│   │   ├── log.h
│   │   ├── logsink.cpp
│   │   ├── logsink.h
│   │   ├── logsource.cpp
│   │   ├── logsource.h
│   │   ├── message.cpp
│   │   ├── message.h
│   │   ├── named_logsource.cpp
│   │   ├── named_logsource.h
│   │   ├── stdout_logsink.cpp
│   │   ├── stdout_logsink.h
│   │   └── test.cpp
│   ├── main/
│   │   ├── CMakeLists.txt
│   │   ├── demo/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── interactive/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── interactive.cpp
│   │   │   │   └── interactive.h
│   │   │   ├── pong/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── aicontroller.cpp
│   │   │   │   ├── aicontroller.h
│   │   │   │   ├── gamestate.cpp
│   │   │   │   ├── gamestate.h
│   │   │   │   ├── gui.cpp
│   │   │   │   ├── gui.h
│   │   │   │   ├── physics.cpp
│   │   │   │   ├── physics.h
│   │   │   │   ├── pong.cpp
│   │   │   │   └── pong.h
│   │   │   └── presenter/
│   │   │       ├── CMakeLists.txt
│   │   │       ├── presenter.cpp
│   │   │       └── presenter.h
│   │   ├── tests.cpp
│   │   └── tests.h
│   ├── main.cpp
│   ├── main.h
│   ├── options.cpp
│   ├── options.h
│   ├── pathfinding/
│   │   ├── CMakeLists.txt
│   │   ├── cost_field.cpp
│   │   ├── cost_field.h
│   │   ├── definitions.cpp
│   │   ├── definitions.h
│   │   ├── demo/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── demo_0.cpp
│   │   │   ├── demo_0.h
│   │   │   ├── demo_1.cpp
│   │   │   ├── demo_1.h
│   │   │   ├── tests.cpp
│   │   │   └── tests.h
│   │   ├── field_cache.cpp
│   │   ├── field_cache.h
│   │   ├── flow_field.cpp
│   │   ├── flow_field.h
│   │   ├── grid.cpp
│   │   ├── grid.h
│   │   ├── integration_field.cpp
│   │   ├── integration_field.h
│   │   ├── integrator.cpp
│   │   ├── integrator.h
│   │   ├── legacy/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── a_star.cpp
│   │   │   ├── a_star.h
│   │   │   ├── heuristics.cpp
│   │   │   ├── heuristics.h
│   │   │   ├── path.cpp
│   │   │   ├── path.h
│   │   │   ├── path_utils.h
│   │   │   └── tests.cpp
│   │   ├── path.cpp
│   │   ├── path.h
│   │   ├── pathfinder.cpp
│   │   ├── pathfinder.h
│   │   ├── portal.cpp
│   │   ├── portal.h
│   │   ├── sector.cpp
│   │   ├── sector.h
│   │   ├── tests.cpp
│   │   ├── types.cpp
│   │   └── types.h
│   ├── presenter/
│   │   ├── CMakeLists.txt
│   │   ├── presenter.cpp
│   │   └── presenter.h
│   ├── pyinterface/
│   │   ├── CMakeLists.txt
│   │   ├── defs.cpp
│   │   ├── defs.h
│   │   ├── exctranslate.cpp
│   │   ├── exctranslate.h
│   │   ├── exctranslate_tests.cpp
│   │   ├── exctranslate_tests.h
│   │   ├── functional.cpp
│   │   ├── functional.h
│   │   ├── hacks.cpp
│   │   ├── hacks.h
│   │   ├── pyexception.cpp
│   │   ├── pyexception.h
│   │   ├── pyobject.cpp
│   │   ├── pyobject.h
│   │   ├── pyobject_tests.cpp
│   │   ├── pyobject_tests.h
│   │   ├── setup.cpp
│   │   └── setup.h
│   ├── renderer/
│   │   ├── CMakeLists.txt
│   │   ├── camera/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── boundaries.cpp
│   │   │   ├── boundaries.h
│   │   │   ├── camera.cpp
│   │   │   ├── camera.h
│   │   │   ├── definitions.cpp
│   │   │   ├── definitions.h
│   │   │   ├── frustum_2d.cpp
│   │   │   ├── frustum_2d.h
│   │   │   ├── frustum_3d.cpp
│   │   │   └── frustum_3d.h
│   │   ├── color.cpp
│   │   ├── color.h
│   │   ├── definitions.cpp
│   │   ├── definitions.h
│   │   ├── demo/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── demo_0.cpp
│   │   │   ├── demo_0.h
│   │   │   ├── demo_1.cpp
│   │   │   ├── demo_1.h
│   │   │   ├── demo_2.cpp
│   │   │   ├── demo_2.h
│   │   │   ├── demo_3.cpp
│   │   │   ├── demo_3.h
│   │   │   ├── demo_4.cpp
│   │   │   ├── demo_4.h
│   │   │   ├── demo_5.cpp
│   │   │   ├── demo_5.h
│   │   │   ├── demo_6.cpp
│   │   │   ├── demo_6.h
│   │   │   ├── demo_7.cpp
│   │   │   ├── demo_7.h
│   │   │   ├── stresstest_0.cpp
│   │   │   ├── stresstest_0.h
│   │   │   ├── stresstest_1.cpp
│   │   │   ├── stresstest_1.h
│   │   │   ├── tests.cpp
│   │   │   ├── tests.h
│   │   │   ├── util.cpp
│   │   │   └── util.h
│   │   ├── font/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── font.cpp
│   │   │   ├── font.h
│   │   │   ├── font_manager.cpp
│   │   │   ├── font_manager.h
│   │   │   ├── glyph_atlas.cpp
│   │   │   ├── glyph_atlas.h
│   │   │   └── tests.cpp
│   │   ├── geometry.cpp
│   │   ├── geometry.h
│   │   ├── gui/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── gui.cpp
│   │   │   ├── gui.h
│   │   │   ├── guisys/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── link/
│   │   │   │   │   ├── gui_item.cpp
│   │   │   │   │   ├── gui_item.h
│   │   │   │   │   ├── gui_item_link.h
│   │   │   │   │   ├── gui_item_list_model.h
│   │   │   │   │   ├── gui_list_model.cpp
│   │   │   │   │   ├── gui_list_model.h
│   │   │   │   │   ├── gui_property_map_impl.cpp
│   │   │   │   │   ├── gui_property_map_impl.h
│   │   │   │   │   ├── gui_singleton_item.cpp
│   │   │   │   │   ├── gui_singleton_item.h
│   │   │   │   │   └── qtgui_checked_static_cast.h
│   │   │   │   ├── private/
│   │   │   │   │   ├── gui_application_impl.cpp
│   │   │   │   │   ├── gui_application_impl.h
│   │   │   │   │   ├── gui_ctx_setup.cpp
│   │   │   │   │   ├── gui_ctx_setup.h
│   │   │   │   │   ├── gui_engine_impl.cpp
│   │   │   │   │   ├── gui_engine_impl.h
│   │   │   │   │   ├── gui_input_impl.cpp
│   │   │   │   │   ├── gui_input_impl.h
│   │   │   │   │   ├── gui_renderer_impl.cpp
│   │   │   │   │   ├── gui_renderer_impl.h
│   │   │   │   │   ├── gui_rendering_setup_routines.cpp
│   │   │   │   │   ├── gui_rendering_setup_routines.h
│   │   │   │   │   ├── gui_subtree_impl.cpp
│   │   │   │   │   ├── gui_subtree_impl.h
│   │   │   │   │   ├── livereload/
│   │   │   │   │   │   ├── deferred_initial_constant_property_values.cpp
│   │   │   │   │   │   ├── deferred_initial_constant_property_values.h
│   │   │   │   │   │   ├── gui_live_reloader.cpp
│   │   │   │   │   │   ├── gui_live_reloader.h
│   │   │   │   │   │   ├── recursive_directory_watcher.cpp
│   │   │   │   │   │   ├── recursive_directory_watcher.h
│   │   │   │   │   │   ├── recursive_directory_watcher_worker.cpp
│   │   │   │   │   │   └── recursive_directory_watcher_worker.h
│   │   │   │   │   ├── opengl_debug_logger.cpp
│   │   │   │   │   └── opengl_debug_logger.h
│   │   │   │   └── public/
│   │   │   │       ├── gui_application.cpp
│   │   │   │       ├── gui_application.h
│   │   │   │       ├── gui_engine.cpp
│   │   │   │       ├── gui_engine.h
│   │   │   │       ├── gui_input.cpp
│   │   │   │       ├── gui_input.h
│   │   │   │       ├── gui_renderer.cpp
│   │   │   │       ├── gui_renderer.h
│   │   │   │       ├── gui_subtree.cpp
│   │   │   │       └── gui_subtree.h
│   │   │   └── integration/
│   │   │       ├── CMakeLists.txt
│   │   │       ├── private/
│   │   │       │   ├── CMakeLists.txt
│   │   │       │   ├── gui_filled_texture_handles.cpp
│   │   │       │   ├── gui_filled_texture_handles.h
│   │   │       │   ├── gui_log.cpp
│   │   │       │   ├── gui_log.h
│   │   │       │   ├── gui_make_standalone_subtexture.cpp
│   │   │       │   ├── gui_make_standalone_subtexture.h
│   │   │       │   ├── gui_standalone_subtexture.cpp
│   │   │       │   ├── gui_standalone_subtexture.h
│   │   │       │   ├── gui_texture.cpp
│   │   │       │   ├── gui_texture.h
│   │   │       │   ├── gui_texture_handle.cpp
│   │   │       │   └── gui_texture_handle.h
│   │   │       └── public/
│   │   │           ├── CMakeLists.txt
│   │   │           ├── gui_application_with_logger.cpp
│   │   │           └── gui_application_with_logger.h
│   │   ├── opengl/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── buffer.cpp
│   │   │   ├── buffer.h
│   │   │   ├── context.cpp
│   │   │   ├── context.h
│   │   │   ├── debug.cpp
│   │   │   ├── debug.h
│   │   │   ├── error.cpp
│   │   │   ├── error.h
│   │   │   ├── framebuffer.cpp
│   │   │   ├── framebuffer.h
│   │   │   ├── geometry.cpp
│   │   │   ├── geometry.h
│   │   │   ├── lookup.h
│   │   │   ├── render_pass.cpp
│   │   │   ├── render_pass.h
│   │   │   ├── render_target.cpp
│   │   │   ├── render_target.h
│   │   │   ├── renderer.cpp
│   │   │   ├── renderer.h
│   │   │   ├── shader.cpp
│   │   │   ├── shader.h
│   │   │   ├── shader_data.cpp
│   │   │   ├── shader_data.h
│   │   │   ├── shader_program.cpp
│   │   │   ├── shader_program.h
│   │   │   ├── simple_object.cpp
│   │   │   ├── simple_object.h
│   │   │   ├── texture.cpp
│   │   │   ├── texture.h
│   │   │   ├── texture_array.cpp
│   │   │   ├── texture_array.h
│   │   │   ├── uniform_buffer.cpp
│   │   │   ├── uniform_buffer.h
│   │   │   ├── uniform_input.cpp
│   │   │   ├── uniform_input.h
│   │   │   ├── util.cpp
│   │   │   ├── util.h
│   │   │   ├── vertex_array.cpp
│   │   │   ├── vertex_array.h
│   │   │   ├── window.cpp
│   │   │   └── window.h
│   │   ├── render_factory.cpp
│   │   ├── render_factory.h
│   │   ├── render_pass.cpp
│   │   ├── render_pass.h
│   │   ├── render_target.cpp
│   │   ├── render_target.h
│   │   ├── renderable.cpp
│   │   ├── renderable.h
│   │   ├── renderer.cpp
│   │   ├── renderer.h
│   │   ├── resources/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── animation/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── angle_info.cpp
│   │   │   │   ├── angle_info.h
│   │   │   │   ├── animation_info.cpp
│   │   │   │   ├── animation_info.h
│   │   │   │   ├── frame_info.cpp
│   │   │   │   ├── frame_info.h
│   │   │   │   ├── layer_info.cpp
│   │   │   │   └── layer_info.h
│   │   │   ├── assets/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── asset_manager.cpp
│   │   │   │   ├── asset_manager.h
│   │   │   │   ├── cache.cpp
│   │   │   │   ├── cache.h
│   │   │   │   ├── texture_manager.cpp
│   │   │   │   └── texture_manager.h
│   │   │   ├── buffer_info.cpp
│   │   │   ├── buffer_info.h
│   │   │   ├── frame_timing.cpp
│   │   │   ├── frame_timing.h
│   │   │   ├── mesh_data.cpp
│   │   │   ├── mesh_data.h
│   │   │   ├── palette_info.cpp
│   │   │   ├── palette_info.h
│   │   │   ├── parser/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── common.cpp
│   │   │   │   ├── common.h
│   │   │   │   ├── parse_blendmask.cpp
│   │   │   │   ├── parse_blendmask.h
│   │   │   │   ├── parse_blendtable.cpp
│   │   │   │   ├── parse_blendtable.h
│   │   │   │   ├── parse_palette.cpp
│   │   │   │   ├── parse_palette.h
│   │   │   │   ├── parse_sprite.cpp
│   │   │   │   ├── parse_sprite.h
│   │   │   │   ├── parse_terrain.cpp
│   │   │   │   ├── parse_terrain.h
│   │   │   │   ├── parse_texture.cpp
│   │   │   │   └── parse_texture.h
│   │   │   ├── shader_source.cpp
│   │   │   ├── shader_source.h
│   │   │   ├── shader_template.cpp
│   │   │   ├── shader_template.h
│   │   │   ├── terrain/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── blendpattern_info.cpp
│   │   │   │   ├── blendpattern_info.h
│   │   │   │   ├── blendtable_info.cpp
│   │   │   │   ├── blendtable_info.h
│   │   │   │   ├── frame_info.cpp
│   │   │   │   ├── frame_info.h
│   │   │   │   ├── layer_info.cpp
│   │   │   │   ├── layer_info.h
│   │   │   │   ├── terrain_info.cpp
│   │   │   │   └── terrain_info.h
│   │   │   ├── texture_data.cpp
│   │   │   ├── texture_data.h
│   │   │   ├── texture_info.cpp
│   │   │   ├── texture_info.h
│   │   │   ├── texture_subinfo.cpp
│   │   │   └── texture_subinfo.h
│   │   ├── shader_program.cpp
│   │   ├── shader_program.h
│   │   ├── stages/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── camera/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── manager.cpp
│   │   │   │   └── manager.h
│   │   │   ├── hud/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── object.cpp
│   │   │   │   ├── object.h
│   │   │   │   ├── render_entity.cpp
│   │   │   │   ├── render_entity.h
│   │   │   │   ├── render_stage.cpp
│   │   │   │   └── render_stage.h
│   │   │   ├── render_entity.cpp
│   │   │   ├── render_entity.h
│   │   │   ├── screen/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── render_stage.cpp
│   │   │   │   ├── render_stage.h
│   │   │   │   ├── screenshot.cpp
│   │   │   │   └── screenshot.h
│   │   │   ├── skybox/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── render_stage.cpp
│   │   │   │   └── render_stage.h
│   │   │   ├── terrain/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── chunk.cpp
│   │   │   │   ├── chunk.h
│   │   │   │   ├── mesh.cpp
│   │   │   │   ├── mesh.h
│   │   │   │   ├── model.cpp
│   │   │   │   ├── model.h
│   │   │   │   ├── render_entity.cpp
│   │   │   │   ├── render_entity.h
│   │   │   │   ├── render_stage.cpp
│   │   │   │   └── render_stage.h
│   │   │   └── world/
│   │   │       ├── CMakeLists.txt
│   │   │       ├── object.cpp
│   │   │       ├── object.h
│   │   │       ├── render_entity.cpp
│   │   │       ├── render_entity.h
│   │   │       ├── render_stage.cpp
│   │   │       └── render_stage.h
│   │   ├── texture.cpp
│   │   ├── texture.h
│   │   ├── texture_array.cpp
│   │   ├── texture_array.h
│   │   ├── types.cpp
│   │   ├── types.h
│   │   ├── uniform_buffer.cpp
│   │   ├── uniform_buffer.h
│   │   ├── uniform_input.cpp
│   │   ├── uniform_input.h
│   │   ├── util.cpp
│   │   ├── util.h
│   │   ├── vulkan/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── README.md
│   │   │   ├── graphics_device.cpp
│   │   │   ├── graphics_device.h
│   │   │   ├── loader.cpp
│   │   │   ├── loader.h
│   │   │   ├── render_target.h
│   │   │   ├── renderer.cpp
│   │   │   ├── renderer.h
│   │   │   ├── shader_program.h
│   │   │   ├── util.h
│   │   │   ├── windowvk.cpp
│   │   │   └── windowvk.h
│   │   ├── window.cpp
│   │   ├── window.h
│   │   ├── window_event_handler.cpp
│   │   └── window_event_handler.h
│   ├── rng/
│   │   ├── CMakeLists.txt
│   │   ├── global_rng.cpp
│   │   ├── global_rng.h
│   │   ├── rng.cpp
│   │   ├── rng.h
│   │   └── rng_tests.cpp
│   ├── testing/
│   │   ├── CMakeLists.txt
│   │   ├── benchmark_test.cpp
│   │   ├── testing.cpp
│   │   ├── testing.h
│   │   ├── testlist.cpp.template
│   │   └── testlist.h
│   ├── time/
│   │   ├── CMakeLists.txt
│   │   ├── clock.cpp
│   │   ├── clock.h
│   │   ├── time.cpp
│   │   ├── time.h
│   │   ├── time_loop.cpp
│   │   └── time_loop.h
│   ├── util/
│   │   ├── CMakeLists.txt
│   │   ├── algorithm.h
│   │   ├── color.cpp
│   │   ├── color.h
│   │   ├── compiler.cpp
│   │   ├── compiler.h
│   │   ├── compress/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── bitstream.h
│   │   │   ├── lzxd.cpp
│   │   │   └── lzxd.h
│   │   ├── consteval.h
│   │   ├── constinit_vector.cpp
│   │   ├── constinit_vector.h
│   │   ├── enum.cpp
│   │   ├── enum.h
│   │   ├── enum_test.cpp
│   │   ├── enum_test.h
│   │   ├── externalprofiler.cpp
│   │   ├── externalprofiler.h
│   │   ├── externalsstream.cpp
│   │   ├── externalsstream.h
│   │   ├── fds.cpp
│   │   ├── fds.h
│   │   ├── file.cpp
│   │   ├── file.h
│   │   ├── filelike/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── filelike.cpp
│   │   │   ├── filelike.h
│   │   │   ├── native.cpp
│   │   │   ├── native.h
│   │   │   ├── python.cpp
│   │   │   └── python.h
│   │   ├── fixed_point.cpp
│   │   ├── fixed_point.h
│   │   ├── fixed_point_test.cpp
│   │   ├── fps.cpp
│   │   ├── fps.h
│   │   ├── fslike/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── directory.cpp
│   │   │   ├── directory.h
│   │   │   ├── fslike.cpp
│   │   │   ├── fslike.h
│   │   │   ├── native.cpp
│   │   │   ├── native.h
│   │   │   ├── python.cpp
│   │   │   └── python.h
│   │   ├── hash.cpp
│   │   ├── hash.h
│   │   ├── hash_test.cpp
│   │   ├── init.cpp
│   │   ├── init.h
│   │   ├── language.cpp
│   │   ├── language.h
│   │   ├── macro/
│   │   │   ├── concat.h
│   │   │   └── loop.h
│   │   ├── math.h
│   │   ├── math_constants.h
│   │   ├── matrix.cpp
│   │   ├── matrix.h
│   │   ├── matrix_test.cpp
│   │   ├── misc.cpp
│   │   ├── misc.h
│   │   ├── misc_test.cpp
│   │   ├── os.cpp
│   │   ├── os.h
│   │   ├── path.cpp
│   │   ├── path.h
│   │   ├── pty.h
│   │   ├── quaternion.cpp
│   │   ├── quaternion.h
│   │   ├── quaternion_test.cpp
│   │   ├── repr.cpp
│   │   ├── repr.h
│   │   ├── signal.h
│   │   ├── stringformatter.cpp
│   │   ├── stringformatter.h
│   │   ├── strings.cpp
│   │   ├── strings.h
│   │   ├── subprocess.cpp
│   │   ├── subprocess.h
│   │   ├── thread_id.cpp
│   │   ├── thread_id.h
│   │   ├── timer.cpp
│   │   ├── timer.h
│   │   ├── timing.cpp
│   │   ├── timing.h
│   │   ├── unicode.cpp
│   │   ├── unicode.h
│   │   ├── variable.h
│   │   ├── vector.cpp
│   │   ├── vector.h
│   │   └── vector_test.cpp
│   ├── version.cpp.in
│   ├── version.h.in
│   └── versions/
│       ├── CMakeLists.txt
│       ├── compiletime.cpp.in
│       ├── compiletime.h.in
│       ├── versions.cpp
│       └── versions.h
├── nix/
│   ├── nyan.nix
│   └── openage.nix
├── openage/
│   ├── .gitignore
│   ├── CMakeLists.txt
│   ├── __init__.py
│   ├── __main__.py
│   ├── assets.py
│   ├── cabextract/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── cab.py
│   │   ├── cabchecksum.pyx
│   │   ├── gen_test_arc.sh
│   │   ├── lzxd.pyx
│   │   ├── lzxdstream.py
│   │   └── test.py
│   ├── codegen/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── codegen.py
│   │   ├── coord.py
│   │   ├── cpp_testlist.py
│   │   ├── listing.py
│   │   └── main.py
│   ├── config.py.in
│   ├── convert/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── entity_object/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── __init__.py
│   │   │   ├── conversion/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── __init__.py
│   │   │   │   ├── aoc/
│   │   │   │   │   ├── CMakeLists.txt
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── genie_civ.py
│   │   │   │   │   ├── genie_connection.py
│   │   │   │   │   ├── genie_effect.py
│   │   │   │   │   ├── genie_graphic.py
│   │   │   │   │   ├── genie_object_container.py
│   │   │   │   │   ├── genie_sound.py
│   │   │   │   │   ├── genie_tech.py
│   │   │   │   │   ├── genie_terrain.py
│   │   │   │   │   └── genie_unit.py
│   │   │   │   ├── combined_sound.py
│   │   │   │   ├── combined_sprite.py
│   │   │   │   ├── combined_terrain.py
│   │   │   │   ├── converter_object.py
│   │   │   │   ├── modpack.py
│   │   │   │   ├── ror/
│   │   │   │   │   ├── CMakeLists.txt
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── genie_sound.py
│   │   │   │   │   ├── genie_tech.py
│   │   │   │   │   └── genie_unit.py
│   │   │   │   ├── stringresource.py
│   │   │   │   └── swgbcc/
│   │   │   │       ├── CMakeLists.txt
│   │   │   │       ├── __init__.py
│   │   │   │       ├── genie_tech.py
│   │   │   │       └── genie_unit.py
│   │   │   └── export/
│   │   │       ├── CMakeLists.txt
│   │   │       ├── __init__.py
│   │   │       ├── data_definition.py
│   │   │       ├── formats/
│   │   │       │   ├── CMakeLists.txt
│   │   │       │   ├── __init__.py
│   │   │       │   ├── blmask_metadata.py
│   │   │       │   ├── bltable_metadata.py
│   │   │       │   ├── media_cache.py
│   │   │       │   ├── modpack_info.py
│   │   │       │   ├── modpack_manifest.py
│   │   │       │   ├── nyan_file.py
│   │   │       │   ├── palette_metadata.py
│   │   │       │   ├── sprite_metadata.py
│   │   │       │   ├── terrain_metadata.py
│   │   │       │   └── texture_metadata.py
│   │   │       ├── media_export_request.py
│   │   │       ├── metadata_export.py
│   │   │       └── texture.py
│   │   ├── main.py
│   │   ├── processor/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── __init__.py
│   │   │   ├── conversion/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── __init__.py
│   │   │   │   ├── aoc/
│   │   │   │   │   ├── CMakeLists.txt
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── ability_subprocessor.py
│   │   │   │   │   ├── auxiliary_subprocessor.py
│   │   │   │   │   ├── civ_subprocessor.py
│   │   │   │   │   ├── effect_subprocessor.py
│   │   │   │   │   ├── media_subprocessor.py
│   │   │   │   │   ├── modifier_subprocessor.py
│   │   │   │   │   ├── modpack_subprocessor.py
│   │   │   │   │   ├── nyan_subprocessor.py
│   │   │   │   │   ├── pregen_processor.py
│   │   │   │   │   ├── processor.py
│   │   │   │   │   ├── tech_subprocessor.py
│   │   │   │   │   ├── upgrade_ability_subprocessor.py
│   │   │   │   │   ├── upgrade_attribute_subprocessor.py
│   │   │   │   │   ├── upgrade_effect_subprocessor.py
│   │   │   │   │   └── upgrade_resource_subprocessor.py
│   │   │   │   ├── aoc_demo/
│   │   │   │   │   ├── CMakeLists.txt
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── modpack_subprocessor.py
│   │   │   │   │   └── processor.py
│   │   │   │   ├── de1/
│   │   │   │   │   ├── CMakeLists.txt
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── media_subprocessor.py
│   │   │   │   │   ├── modpack_subprocessor.py
│   │   │   │   │   └── processor.py
│   │   │   │   ├── de2/
│   │   │   │   │   ├── CMakeLists.txt
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── ability_subprocessor.py
│   │   │   │   │   ├── civ_subprocessor.py
│   │   │   │   │   ├── media_subprocessor.py
│   │   │   │   │   ├── modpack_subprocessor.py
│   │   │   │   │   ├── nyan_subprocessor.py
│   │   │   │   │   ├── processor.py
│   │   │   │   │   ├── tech_subprocessor.py
│   │   │   │   │   ├── upgrade_attribute_subprocessor.py
│   │   │   │   │   └── upgrade_resource_subprocessor.py
│   │   │   │   ├── hd/
│   │   │   │   │   ├── CMakeLists.txt
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── media_subprocessor.py
│   │   │   │   │   ├── modpack_subprocessor.py
│   │   │   │   │   └── processor.py
│   │   │   │   ├── ror/
│   │   │   │   │   ├── CMakeLists.txt
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── ability_subprocessor.py
│   │   │   │   │   ├── auxiliary_subprocessor.py
│   │   │   │   │   ├── civ_subprocessor.py
│   │   │   │   │   ├── media_subprocessor.py
│   │   │   │   │   ├── modpack_subprocessor.py
│   │   │   │   │   ├── nyan_subprocessor.py
│   │   │   │   │   ├── pregen_subprocessor.py
│   │   │   │   │   ├── processor.py
│   │   │   │   │   ├── tech_subprocessor.py
│   │   │   │   │   ├── upgrade_ability_subprocessor.py
│   │   │   │   │   ├── upgrade_attribute_subprocessor.py
│   │   │   │   │   └── upgrade_resource_subprocessor.py
│   │   │   │   └── swgbcc/
│   │   │   │       ├── CMakeLists.txt
│   │   │   │       ├── __init__.py
│   │   │   │       ├── ability_subprocessor.py
│   │   │   │       ├── auxiliary_subprocessor.py
│   │   │   │       ├── civ_subprocessor.py
│   │   │   │       ├── modpack_subprocessor.py
│   │   │   │       ├── nyan_subprocessor.py
│   │   │   │       ├── pregen_subprocessor.py
│   │   │   │       ├── processor.py
│   │   │   │       ├── tech_subprocessor.py
│   │   │   │       ├── upgrade_attribute_subprocessor.py
│   │   │   │       └── upgrade_resource_subprocessor.py
│   │   │   └── export/
│   │   │       ├── CMakeLists.txt
│   │   │       ├── __init__.pxd
│   │   │       ├── __init__.py
│   │   │       ├── data_exporter.py
│   │   │       ├── generate_manifest_hashes.py
│   │   │       ├── media_exporter.py
│   │   │       ├── modpack_exporter.py
│   │   │       ├── terrain_merge.pyx
│   │   │       └── texture_merge.pyx
│   │   ├── service/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── __init__.py
│   │   │   ├── conversion/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── __init__.py
│   │   │   │   └── internal_name_lookups.py
│   │   │   ├── debug_info.py
│   │   │   ├── export/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── __init__.py
│   │   │   │   ├── interface/
│   │   │   │   │   ├── CMakeLists.txt
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── cutter.py
│   │   │   │   │   ├── rename.py
│   │   │   │   │   └── visgrep.pyx
│   │   │   │   ├── load_media_cache.py
│   │   │   │   ├── opus/
│   │   │   │   │   ├── CMakeLists.txt
│   │   │   │   │   ├── __init__.pxd
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── bytearray.pxd
│   │   │   │   │   ├── demo.py
│   │   │   │   │   ├── ogg.pxd
│   │   │   │   │   ├── opus.pxd
│   │   │   │   │   └── opusenc.pyx
│   │   │   │   └── png/
│   │   │   │       ├── CMakeLists.txt
│   │   │   │       ├── __init__.pxd
│   │   │   │       ├── __init__.py
│   │   │   │       ├── binpack.pxd
│   │   │   │       ├── binpack.pyx
│   │   │   │       ├── libpng.pxd
│   │   │   │       ├── png_create.pyx
│   │   │   │       └── png_tmp_file.pxd
│   │   │   ├── init/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── __init__.py
│   │   │   │   ├── api_export_required.py
│   │   │   │   ├── changelog.py
│   │   │   │   ├── modpack_search.py
│   │   │   │   ├── mount_asset_dirs.py
│   │   │   │   └── version_detect.py
│   │   │   └── read/
│   │   │       ├── CMakeLists.txt
│   │   │       ├── __init__.py
│   │   │       ├── gamedata.py
│   │   │       ├── nyan_api_loader.py
│   │   │       ├── palette.py
│   │   │       ├── register_media.py
│   │   │       └── string_resource.py
│   │   ├── tool/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── __init__.py
│   │   │   ├── api_export.py
│   │   │   ├── driver.py
│   │   │   ├── interactive.py
│   │   │   ├── singlefile.py
│   │   │   └── subtool/
│   │   │       ├── CMakeLists.txt
│   │   │       ├── __init__.py
│   │   │       ├── acquire_sourcedir.py
│   │   │       └── version_select.py
│   │   └── value_object/
│   │       ├── CMakeLists.txt
│   │       ├── __init__.py
│   │       ├── conversion/
│   │       │   ├── CMakeLists.txt
│   │       │   ├── __init__.py
│   │       │   ├── aoc/
│   │       │   │   ├── CMakeLists.txt
│   │       │   │   ├── __init__.py
│   │       │   │   └── internal_nyan_names.py
│   │       │   ├── de1/
│   │       │   │   ├── CMakeLists.txt
│   │       │   │   ├── __init__.py
│   │       │   │   └── internal_nyan_names.py
│   │       │   ├── de2/
│   │       │   │   ├── CMakeLists.txt
│   │       │   │   ├── __init__.py
│   │       │   │   └── internal_nyan_names.py
│   │       │   ├── forward_ref.py
│   │       │   ├── hd/
│   │       │   │   ├── CMakeLists.txt
│   │       │   │   ├── __init__.py
│   │       │   │   ├── ak/
│   │       │   │   │   ├── CMakeLists.txt
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   └── internal_nyan_names.py
│   │       │   │   ├── fgt/
│   │       │   │   │   ├── CMakeLists.txt
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   └── internal_nyan_names.py
│   │       │   │   └── raj/
│   │       │   │       ├── CMakeLists.txt
│   │       │   │       ├── __init__.py
│   │       │   │       └── internal_nyan_names.py
│   │       │   ├── ror/
│   │       │   │   ├── CMakeLists.txt
│   │       │   │   ├── __init__.py
│   │       │   │   └── internal_nyan_names.py
│   │       │   └── swgb/
│   │       │       ├── CMakeLists.txt
│   │       │       ├── __init__.py
│   │       │       └── internal_nyan_names.py
│   │       ├── init/
│   │       │   ├── CMakeLists.txt
│   │       │   ├── __init__.py
│   │       │   ├── game_file_version.py
│   │       │   └── game_version.py
│   │       └── read/
│   │           ├── CMakeLists.txt
│   │           ├── __init__.py
│   │           ├── dynamic_loader.py
│   │           ├── genie_structure.py
│   │           ├── media/
│   │           │   ├── CMakeLists.txt
│   │           │   ├── __init__.pxd
│   │           │   ├── __init__.py
│   │           │   ├── blendomatic.py
│   │           │   ├── colortable.py
│   │           │   ├── datfile/
│   │           │   │   ├── CMakeLists.txt
│   │           │   │   ├── __init__.py
│   │           │   │   ├── civ.py
│   │           │   │   ├── empiresdat.py
│   │           │   │   ├── graphic.py
│   │           │   │   ├── lookup_dicts.py
│   │           │   │   ├── maps.py
│   │           │   │   ├── playercolor.py
│   │           │   │   ├── research.py
│   │           │   │   ├── sound.py
│   │           │   │   ├── tech.py
│   │           │   │   ├── terrain.py
│   │           │   │   └── unit.py
│   │           │   ├── drs.py
│   │           │   ├── hardcoded/
│   │           │   │   ├── CMakeLists.txt
│   │           │   │   ├── __init__.py
│   │           │   │   ├── interface.py
│   │           │   │   ├── termcolors.py
│   │           │   │   ├── terrain_tile_size.py
│   │           │   │   └── texture.py
│   │           │   ├── langcodes.py
│   │           │   ├── pefile.py
│   │           │   ├── peresource.py
│   │           │   ├── sld.pyx
│   │           │   ├── slp.pyx
│   │           │   ├── smp.pyx
│   │           │   └── smx.pyx
│   │           ├── media_types.py
│   │           ├── member_access.py
│   │           ├── read_members.py
│   │           └── value_members.py
│   ├── cppinterface/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── exctranslate.pyx
│   │   ├── exctranslate_tests.pyx
│   │   ├── pyobject.pyx
│   │   ├── setup.py
│   │   ├── setup_checker.pyx
│   │   └── typedefs.pxd
│   ├── cvar/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── config_file.py
│   │   ├── cvar.pyx
│   │   └── location.py
│   ├── cython_check.pyx
│   ├── default_dirs.py
│   ├── devmode.py
│   ├── event/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   └── demo.pyx
│   ├── game/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── main.py
│   │   └── main_cpp.pyx
│   ├── gamestate/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   └── tests.pyx
│   ├── log/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── log_cpp.pyx
│   │   └── tests.py
│   ├── main/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── main.py
│   │   ├── main_cpp.pyx
│   │   └── tests.pyx
│   ├── nyan/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── import_tree.py
│   │   └── nyan_structs.py
│   ├── pathfinding/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   └── tests.pyx
│   ├── renderer/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── renderer_cpp.pyx
│   │   └── tests.pyx
│   ├── testing/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── benchmark.py
│   │   ├── cpp_testing.pyx
│   │   ├── doctest.py
│   │   ├── list_processor.py
│   │   ├── main.py
│   │   ├── misc_cpp.pyx
│   │   ├── testing.py
│   │   └── testlist.py
│   ├── util/
│   │   ├── CMakeLists.txt
│   │   ├── __init__.py
│   │   ├── bytequeue.py
│   │   ├── context.py
│   │   ├── decorators.py
│   │   ├── dll.py
│   │   ├── filelike/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── __init__.py
│   │   │   ├── abstract.py
│   │   │   ├── cpp.pyx
│   │   │   ├── fifo.py
│   │   │   ├── readonly.py
│   │   │   └── stream.py
│   │   ├── files.py
│   │   ├── fslike/
│   │   │   ├── CMakeLists.txt
│   │   │   ├── __init__.py
│   │   │   ├── abstract.py
│   │   │   ├── cpp.pxd
│   │   │   ├── cpp.pyx
│   │   │   ├── directory.py
│   │   │   ├── filecollection.py
│   │   │   ├── path.py
│   │   │   ├── test.py
│   │   │   ├── union.py
│   │   │   └── wrapper.py
│   │   ├── fsprinting.py
│   │   ├── hash.py
│   │   ├── iterators.py
│   │   ├── math.py
│   │   ├── observer.py
│   │   ├── ordered_set.py
│   │   ├── profiler.py
│   │   ├── strings.py
│   │   ├── struct.py
│   │   ├── system.py
│   │   ├── threading.py
│   │   └── version.py
│   └── versions/
│       ├── CMakeLists.txt
│       ├── __init__.py
│       └── versions.pyx
├── openage_version
├── packaging/
│   ├── CMakeLists.txt
│   ├── CPackOptions.cmake
│   └── docker/
│       └── devenv/
│           └── Dockerfile.ubuntu.2404
├── run.py.in
└── shell.nix
Download .txt
Showing preview only (338K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (3891 symbols across 989 files)

FILE: buildsystem/check_py_file_list.py
  function main (line 13) | def main():

FILE: buildsystem/codecompliance/__main__.py
  function parse_args (line 17) | def parse_args():
  function process_args (line 75) | def process_args(args, error):
  function get_changed_files (line 147) | def get_changed_files(gitref):
  function main (line 165) | def main(args):
  function find_all_issues (line 224) | def find_all_issues(args, check_files=None):

FILE: buildsystem/codecompliance/authors.py
  function deobfuscate_email (line 14) | def deobfuscate_email(string):
  function get_author_emails_copying_md (line 32) | def get_author_emails_copying_md():
  function get_author_emails_git_shortlog (line 57) | def get_author_emails_git_shortlog(exts):
  function find_issues (line 81) | def find_issues():

FILE: buildsystem/codecompliance/clangtidy.py
  function find_issues (line 12) | def find_issues(check_files, dirnames):

FILE: buildsystem/codecompliance/cppstyle.py
  function filter_file_list (line 51) | def filter_file_list(check_files, dirnames):
  function find_issues (line 68) | def find_issues(check_files, dirnames):
  function find_issues_with_lines (line 93) | def find_issues_with_lines(data, filename):

FILE: buildsystem/codecompliance/cython.py
  function filter_file_list (line 25) | def filter_file_list(check_files, dirnames):
  function find_issues (line 38) | def find_issues(check_files, dirnames):

FILE: buildsystem/codecompliance/headerguards.py
  class HeaderIssue (line 12) | class HeaderIssue(Exception):
  function find_issues (line 33) | def find_issues(dirname):

FILE: buildsystem/codecompliance/legal.py
  function get_git_change_year (line 60) | def get_git_change_year(filename):
  function match_legalheader (line 78) | def match_legalheader(data):
  function create_year_fix (line 95) | def create_year_fix(filename, file_content, expected_end_year,
  function test_headers (line 127) | def test_headers(check_files, paths, git_change_years, third_party_files):
  function find_issues (line 193) | def find_issues(check_files, paths, git_change_years=False):

FILE: buildsystem/codecompliance/modes.py
  function check_mode (line 27) | def check_mode(filename):
  function find_issues (line 52) | def find_issues(check_files, paths):

FILE: buildsystem/codecompliance/pylint.py
  function find_pyx_modules (line 13) | def find_pyx_modules(dirnames):
  function find_issues (line 19) | def find_issues(check_files, dirnames):

FILE: buildsystem/codecompliance/pystyle.py
  function filter_file_list (line 22) | def filter_file_list(check_files, dirnames):
  function find_issues (line 35) | def find_issues(check_files, dirnames):

FILE: buildsystem/codecompliance/textfiles.py
  function find_issues (line 22) | def find_issues(dirnames, exts):
  function find_issues_with_lines (line 62) | def find_issues_with_lines(filename):

FILE: buildsystem/codecompliance/util.py
  function log_setup (line 17) | def log_setup(setting, default=1):
  function clamp (line 36) | def clamp(number, smallest, largest):
  class Strlazy (line 41) | class Strlazy:
    method __init__ (line 48) | def __init__(self, fun):
    method __str__ (line 51) | def __str__(self):
  function has_ext (line 55) | def has_ext(fname, exts):
  function readfile (line 69) | def readfile(filename):
  function writefile (line 91) | def writefile(filename, new_content):
  function findfiles (line 104) | def findfiles(paths, exts=None):
  function issue_str (line 127) | def issue_str(title, filename, fix=None):
  function issue_str_line (line 139) | def issue_str_line(title, filename, line, line_number, highlight, fix=No...

FILE: buildsystem/compilepy.py
  function clone_file_to_dir (line 15) | def clone_file_to_dir(sourcefile, input_dir, output_dir):
  function main (line 50) | def main():

FILE: buildsystem/cythonize.py
  class LineFilter (line 19) | class LineFilter:
    method __init__ (line 22) | def __init__(self, stream=None, filters=None):
    method __getattr__ (line 27) | def __getattr__(self, attr_name):
    method __enter__ (line 30) | def __enter__(self):
    method __exit__ (line 33) | def __exit__(self, *args):
    method write (line 37) | def write(self, data):
  class CythonFilter (line 50) | class CythonFilter(LineFilter):
    method __init__ (line 53) | def __init__(self):
  function read_list_from_file (line 61) | def read_list_from_file(filename):
  function remove_if_exists (line 69) | def remove_if_exists(filename):
  function cythonize_wrapper (line 76) | def cythonize_wrapper(modules, force_optimized_lib = False, **kwargs):
  function win_use_optimized_lib_python (line 102) | def win_use_optimized_lib_python(modules, path):
  function main (line 144) | def main():

FILE: buildsystem/inplacemodules.py
  function main (line 17) | def main():

FILE: buildsystem/modules/FindPython_test.cpp
  function main (line 5) | int main() {

FILE: buildsystem/pxdgen.py
  class ParserError (line 22) | class ParserError(Exception):
    method __init__ (line 27) | def __init__(self, filename, lineno, message):
  class PXDGenerator (line 31) | class PXDGenerator:
    method __init__ (line 41) | def __init__(self, filename):
    method parser_error (line 49) | def parser_error(self, message, lineno=None):
    method tokenize (line 58) | def tokenize(self):
    method handle_singleline_comment (line 85) | def handle_singleline_comment(self, val):
    method handle_multiline_comment (line 100) | def handle_multiline_comment(self, val):
    method handle_comment (line 134) | def handle_comment(self, val):
    method add_annotation (line 160) | def add_annotation(self, annotation_lines):
    method handle_token (line 173) | def handle_token(self, token, val):
    method parse (line 207) | def parse(self):
    method get_pxd_lines (line 280) | def get_pxd_lines(self):
    method postprocess_annotation_line (line 335) | def postprocess_annotation_line(self, annotation):
    method generate (line 364) | def generate(self, pxdfile, ignore_timestamps=False, print_warnings=Tr...
  function parse_args (line 404) | def parse_args():
  function main (line 440) | def main():

FILE: buildsystem/scripts/copy_modules.py
  function copy_module (line 17) | def copy_module(name, destination):
  function main (line 32) | def main():

FILE: etc/gdb_pretty/printers.py
  class PrinterControl (line 14) | class PrinterControl(gdb.printing.PrettyPrinter):
    method __init__ (line 23) | def __init__(self, name: str):
    method add_printer (line 29) | def add_printer(self, type_name: str, printer):
    method add_printer_regex (line 35) | def add_printer_regex(self, regex: str, printer):
    method __call__ (line 44) | def __call__(self, val: gdb.Value):
  function printer_typedef (line 66) | def printer_typedef(type_name: str):
  function printer_regex (line 82) | def printer_regex(regex: str):
  function format_fixed_point (line 98) | def format_fixed_point(value: int, fractional_bits: int) -> float:
  class CoordPrinter (line 112) | class CoordPrinter:
    method __init__ (line 117) | def __init__(self, val: gdb.Value):
    method to_string (line 125) | def to_string(self):
    method children (line 142) | def children(self):
  class TimePrinter (line 151) | class TimePrinter:
    method __init__ (line 156) | def __init__(self, val: gdb.Value):
    method to_string (line 159) | def to_string(self):
    method children (line 173) | def children(self):
  class FixedPointPrinter (line 181) | class FixedPointPrinter:
    method __init__ (line 186) | def __init__(self, val: gdb.Value):
    method to_string (line 189) | def to_string(self):
    method children (line 201) | def children(self):
  class VectorPrinter (line 217) | class VectorPrinter:
    method __init__ (line 222) | def __init__(self, val: gdb.Value):
    method to_string (line 225) | def to_string(self):
    method children (line 233) | def children(self):
    method child (line 241) | def child(self, index):
    method num_children (line 247) | def num_children(self):
    method display_hint (line 254) | def display_hint():
  class KeyframePrinter (line 262) | class KeyframePrinter:
    method __init__ (line 267) | def __init__(self, val: gdb.Value):
    method to_string (line 270) | def to_string(self):
    method children (line 276) | def children(self):
  class PathFlowTypePrinter (line 285) | class PathFlowTypePrinter:
    method __init__ (line 310) | def __init__(self, val: gdb.Value):
    method to_string (line 313) | def to_string(self):
    method children (line 323) | def children(self):
  function get_integrated_flags_list (line 348) | def get_integrated_flags_list(value: int) -> str:
  class PathIntegratedFlagsTypePrinter (line 364) | class PathIntegratedFlagsTypePrinter:
    method __init__ (line 371) | def __init__(self, val: gdb.Value):
    method to_string (line 374) | def to_string(self):
    method children (line 381) | def children(self):
  class PathIntegratedTypePrinter (line 391) | class PathIntegratedTypePrinter:
    method __init__ (line 398) | def __init__(self, val: gdb.Value):
    method to_string (line 401) | def to_string(self):
    method children (line 411) | def children(self):

FILE: libopenage/assets/mod_manager.cpp
  type openage::assets (line 7) | namespace openage::assets {

FILE: libopenage/assets/mod_manager.h
  function namespace (line 17) | namespace openage::assets {

FILE: libopenage/assets/modpack.cpp
  type openage::assets (line 9) | namespace openage::assets {
    function ModpackInfo (line 11) | ModpackInfo parse_modepack_def(const util::Path &info_file) {
    function ModpackInfo (line 210) | const ModpackInfo &Modpack::get_info() const {

FILE: libopenage/assets/modpack.h
  function namespace (line 12) | namespace openage::assets {

FILE: libopenage/audio/audio_manager.cpp
  type openage (line 20) | namespace openage {
    type audio (line 21) | namespace audio {
      function Sound (line 105) | Sound AudioManager::get_sound(category_t category, int id) {

FILE: libopenage/audio/audio_manager.h
  function namespace (line 21) | namespace openage {

FILE: libopenage/audio/category.cpp
  type openage (line 9) | namespace openage {
    type audio (line 10) | namespace audio {

FILE: libopenage/audio/category.h
  function namespace (line 7) | namespace openage::audio {

FILE: libopenage/audio/dynamic_loader.cpp
  type openage (line 8) | namespace openage {
    type audio (line 9) | namespace audio {

FILE: libopenage/audio/dynamic_loader.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/audio/dynamic_resource.cpp
  type openage::audio (line 10) | namespace openage::audio {
    function audio_chunk_t (line 67) | audio_chunk_t DynamicResource::get_data(size_t position, size_t data_l...

FILE: libopenage/audio/dynamic_resource.h
  function namespace (line 21) | namespace openage {

FILE: libopenage/audio/error.cpp
  type openage (line 5) | namespace openage {
    type audio (line 6) | namespace audio {

FILE: libopenage/audio/error.h
  function namespace (line 7) | namespace openage {

FILE: libopenage/audio/format.cpp
  type openage::audio (line 7) | namespace openage::audio {

FILE: libopenage/audio/format.h
  function namespace (line 8) | namespace openage {

FILE: libopenage/audio/hash_functions.h
  function namespace (line 9) | namespace std {

FILE: libopenage/audio/in_memory_loader.cpp
  type openage (line 9) | namespace openage {
    type audio (line 10) | namespace audio {

FILE: libopenage/audio/in_memory_loader.h
  function namespace (line 14) | namespace openage {

FILE: libopenage/audio/in_memory_resource.cpp
  type openage (line 7) | namespace openage {
    type audio (line 8) | namespace audio {
      function audio_chunk_t (line 29) | audio_chunk_t InMemoryResource::get_data(size_t position,

FILE: libopenage/audio/in_memory_resource.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/audio/loader_policy.cpp
  type openage (line 7) | namespace openage {
    type audio (line 8) | namespace audio {

FILE: libopenage/audio/loader_policy.h
  function namespace (line 9) | namespace openage {

FILE: libopenage/audio/opus_dynamic_loader.cpp
  type openage::audio (line 10) | namespace openage::audio {

FILE: libopenage/audio/opus_dynamic_loader.h
  function namespace (line 14) | namespace openage {

FILE: libopenage/audio/opus_in_memory_loader.cpp
  type openage (line 13) | namespace openage {
    type audio (line 14) | namespace audio {
      function pcm_data_t (line 21) | pcm_data_t OpusInMemoryLoader::get_resource() {

FILE: libopenage/audio/opus_in_memory_loader.h
  function namespace (line 12) | namespace openage {

FILE: libopenage/audio/opus_loading.cpp
  type openage::audio (line 9) | namespace openage::audio {
    function opus_file_t (line 56) | opus_file_t open_opus_file(const util::Path &path) {

FILE: libopenage/audio/opus_loading.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/audio/resource.cpp
  type openage (line 10) | namespace openage {
    type audio (line 11) | namespace audio {
      function category_t (line 20) | category_t Resource::get_category() const {

FILE: libopenage/audio/resource.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/audio/resource_def.cpp
  type openage (line 5) | namespace openage {
    type audio (line 6) | namespace audio {

FILE: libopenage/audio/resource_def.h
  function namespace (line 14) | namespace openage {

FILE: libopenage/audio/sound.cpp
  type openage::audio (line 11) | namespace openage::audio {
    function category_t (line 21) | category_t Sound::get_category() const {
    function category_t (line 122) | category_t SoundImpl::get_category() const {

FILE: libopenage/audio/sound.h
  function namespace (line 9) | namespace openage {

FILE: libopenage/audio/types.h
  function namespace (line 10) | namespace openage {

FILE: libopenage/console/buf.cpp
  type openage (line 9) | namespace openage {
    type console (line 10) | namespace console {
      class NewBuf (line 77) | class NewBuf {
        method NewBuf (line 102) | NewBuf(term dims, term_t scrollback_lines, buf_char default_char_fmt)
        method apply_to_buf (line 133) | void apply_to_buf(Buf *b) {
        method move_ptrs_to_next_line (line 156) | void move_ptrs_to_next_line() {
        method new_line (line 177) | void new_line(bool part_of_screen_buf) {
        method new_chr (line 191) | void new_chr(buf_char c) {
      function print_cps (line 599) | void print_cps(FILE *f, std::vector<int> *v) {
      function buf_char (line 1141) | buf_char *Buf::chrdataptr(term pos) {
      function buf_line (line 1151) | buf_line *Buf::linedataptr(term_t lineno) {

FILE: libopenage/console/buf.h
  function namespace (line 15) | namespace openage {

FILE: libopenage/console/console.cpp
  type openage (line 12) | namespace openage {
    type console (line 13) | namespace console {

FILE: libopenage/console/console.h
  function namespace (line 12) | namespace openage {

FILE: libopenage/console/draw.cpp
  type openage (line 16) | namespace openage {
    type console (line 17) | namespace console {
      type draw (line 18) | namespace draw {
        function to_terminal (line 90) | void to_terminal(Buf *buf, util::FD *fd, bool clear) {

FILE: libopenage/console/draw.h
  function namespace (line 6) | namespace openage {

FILE: libopenage/console/tests.cpp
  type openage::console::tests (line 25) | namespace openage::console::tests {
    function max (line 29) | int max(int a, int b) {
    function render (line 37) | void render() {
    function interactive (line 53) | void interactive() {

FILE: libopenage/coord/chunk.cpp
  type openage (line 8) | namespace openage {
    type coord (line 9) | namespace coord {
      function tile_delta (line 11) | tile_delta chunk_delta::to_tile(tile_t tiles_per_chunk) const {
      function tile (line 15) | tile chunk::to_tile(tile_t tiles_per_chunk) const {

FILE: libopenage/coord/chunk.h
  function namespace (line 9) | namespace openage {
  type chunk3_delta (line 25) | struct chunk3_delta
  type chunk3 (line 29) | struct chunk3

FILE: libopenage/coord/coord_test.cpp
  type openage (line 10) | namespace openage {
    type coord (line 11) | namespace coord {
      type tests (line 12) | namespace tests {
        type TestCoordsRelative (line 19) | struct TestCoordsRelative
        type TestCoordsAbsolute (line 20) | struct TestCoordsAbsolute
        type TestCoordsAbsolute (line 22) | struct TestCoordsAbsolute : CoordXYAbsolute<int, TestCoordsAbsolut...
        type TestCoordsRelative (line 26) | struct TestCoordsRelative : CoordXYRelative<int, TestCoordsAbsolut...
        function coord (line 36) | void coord() {

FILE: libopenage/coord/declarations.cpp
  type openage::coord (line 5) | namespace openage::coord {

FILE: libopenage/coord/declarations.h
  function namespace (line 16) | namespace openage {

FILE: libopenage/coord/phys.cpp
  type openage::coord (line 12) | namespace openage::coord {
    function phys2_delta (line 20) | phys2_delta phys2_delta::normalize(double length) const {
    function phys3_delta (line 25) | phys3_delta phys2_delta::to_phys3() const {
    function scene2_delta (line 30) | scene2_delta phys2_delta::to_scene2() const {
    function phys_angle_t (line 34) | phys_angle_t phys2_delta::to_angle(const coord::phys2_delta &other) co...
    function tile (line 54) | tile phys2::to_tile() const {
    function phys3 (line 58) | phys3 phys2::to_phys3(phys_t up) const {
    function scene2 (line 62) | scene2 phys2::to_scene2() const {
    function phys3_delta (line 71) | phys3_delta phys3_delta::normalize(double length) const {
    function phys2_delta (line 76) | phys2_delta phys3_delta::to_phys2() const {
    function scene3_delta (line 81) | scene3_delta phys3_delta::to_scene3() const {
    function phys_angle_t (line 85) | phys_angle_t phys3_delta::to_angle(const coord::phys2_delta &other) co...
    function tile3 (line 99) | tile3 phys3::to_tile3() const {
    function tile (line 104) | tile phys3::to_tile() const {
    function phys2 (line 109) | phys2 phys3::to_phys2() const {
    function scene3 (line 114) | scene3 phys3::to_scene3() const {

FILE: libopenage/coord/phys.h
  function namespace (line 11) | namespace openage {
  function namespace (line 82) | namespace std {

FILE: libopenage/coord/pixel.cpp
  type openage (line 10) | namespace openage {
    type coord (line 11) | namespace coord {
      function viewport_delta (line 13) | viewport_delta camhud_delta::to_viewport() const {
      function viewport (line 18) | viewport camhud::to_viewport() const {
      function camhud (line 24) | camhud viewport::to_camhud() const {
      function viewport_delta (line 36) | viewport_delta input_delta::to_viewport(const std::shared_ptr<render...
      function viewport (line 46) | viewport input::to_viewport(const std::shared_ptr<renderer::camera::...
      function phys3 (line 51) | phys3 input::to_phys3(const std::shared_ptr<renderer::camera::Camera...
      function scene3 (line 56) | scene3 input::to_scene3(const std::shared_ptr<renderer::camera::Came...

FILE: libopenage/coord/pixel.h
  function namespace (line 10) | namespace openage {
  type viewport_delta (line 40) | struct viewport_delta
  function camhud_delta (line 44) | camhud_delta to_camhud() const {
  type input_delta (line 61) | struct input_delta
  type input (line 69) | struct input

FILE: libopenage/coord/scene.cpp
  type openage::coord (line 13) | namespace openage::coord {
    function up_ratio (line 22) | constexpr float up_ratio() {
    function scene2_delta (line 33) | scene2_delta scene2_delta::normalize(double length) const {
    function scene3_delta (line 38) | scene3_delta scene2_delta::to_scene3() const {
    function phys2_delta (line 43) | phys2_delta scene2_delta::to_phys2() const {
    function scene3 (line 70) | scene3 scene2::to_scene3(phys_t altitude) const {
    function phys2 (line 75) | phys2 scene2::to_phys2() const {
    function scene3_delta (line 90) | scene3_delta scene3_delta::normalize(double length) const {
    function scene2_delta (line 95) | scene2_delta scene3_delta::to_scene2() const {
    function phys3_delta (line 100) | phys3_delta scene3_delta::to_phys3() const {
    function scene2 (line 113) | scene2 scene3::to_scene2() const {
    function phys3 (line 118) | phys3 scene3::to_phys3() const {

FILE: libopenage/coord/scene.h
  function namespace (line 15) | namespace openage {
  function namespace (line 88) | namespace std {

FILE: libopenage/coord/term.cpp
  type openage (line 5) | namespace openage {
    type coord (line 6) | namespace coord {

FILE: libopenage/coord/term.h
  function namespace (line 8) | namespace openage {

FILE: libopenage/coord/tile.cpp
  type openage::coord (line 9) | namespace openage::coord {
    function phys2_delta (line 11) | phys2_delta tile_delta::to_phys2() const {
    function phys3_delta (line 16) | phys3_delta tile_delta::to_phys3(tile_t up) const {
    function tile3 (line 22) | tile3 tile::to_tile3(tile_t up) const {
    function phys2 (line 26) | phys2 tile::to_phys2() const {
    function phys3 (line 31) | phys3 tile::to_phys3(tile_t up) const {
    function phys2 (line 35) | phys2 tile::to_phys2_center() const {
    function phys3 (line 40) | phys3 tile::to_phys3_center(tile_t up) const {
    function chunk (line 46) | chunk tile::to_chunk() const {
    function tile_delta (line 52) | tile_delta tile::get_pos_on_chunk() const {
    function tile_delta (line 58) | tile_delta tile3_delta::to_tile() const {
    function phys3_delta (line 62) | phys3_delta tile3_delta::to_phys3() const {
    function tile (line 68) | tile tile3::to_tile() const {
    function phys2 (line 72) | phys2 tile3::to_phys2() const {
    function phys3 (line 76) | phys3 tile3::to_phys3() const {
    function phys2 (line 82) | phys2 tile3::to_phys2_center() const {
    function phys3 (line 87) | phys3 tile3::to_phys3_center() const {

FILE: libopenage/coord/tile.h
  function namespace (line 11) | namespace openage {

FILE: libopenage/curve/base_curve.cpp
  type openage::curve (line 5) | namespace openage::curve {

FILE: libopenage/curve/base_curve.h
  function namespace (line 23) | namespace event {
  function virtual (line 56) | virtual T operator()(const time::time_t &now) {

FILE: libopenage/curve/container/array.cpp
  type openage::curve (line 6) | namespace openage::curve {

FILE: libopenage/curve/container/array.h
  function _id (line 51) | init_default_vals(default_vals)},

FILE: libopenage/curve/container/element_wrapper.cpp
  type openage::curve (line 5) | namespace openage::curve {

FILE: libopenage/curve/container/element_wrapper.h
  function namespace (line 7) | namespace openage::curve {

FILE: libopenage/curve/container/iterator.cpp
  type openage::curve (line 5) | namespace openage::curve {

FILE: libopenage/curve/container/iterator.h
  function namespace (line 9) | namespace openage::curve {

FILE: libopenage/curve/container/map.cpp
  type openage::curve (line 5) | namespace openage::curve {

FILE: libopenage/curve/container/map_filter_iterator.cpp
  type openage::curve (line 5) | namespace openage::curve {

FILE: libopenage/curve/container/map_filter_iterator.h
  function namespace (line 9) | namespace openage::curve {

FILE: libopenage/curve/container/queue.cpp
  type openage::curve (line 5) | namespace openage::curve {

FILE: libopenage/curve/container/queue.h
  function namespace (line 22) | namespace openage {

FILE: libopenage/curve/container/queue_filter_iterator.cpp
  type openage::curve (line 5) | namespace openage::curve {

FILE: libopenage/curve/container/queue_filter_iterator.h
  function namespace (line 9) | namespace openage::curve {

FILE: libopenage/curve/continuous.cpp
  type openage::curve (line 5) | namespace openage::curve {

FILE: libopenage/curve/continuous.h
  function namespace (line 12) | namespace openage::curve {

FILE: libopenage/curve/discrete.cpp
  type openage::curve (line 5) | namespace openage::curve {

FILE: libopenage/curve/discrete.h
  function namespace (line 15) | namespace openage::curve {

FILE: libopenage/curve/discrete_mod.cpp
  type openage::curve (line 5) | namespace openage::curve {

FILE: libopenage/curve/discrete_mod.h
  function namespace (line 17) | namespace openage::curve {

FILE: libopenage/curve/interpolated.h
  function namespace (line 10) | namespace openage::curve {

FILE: libopenage/curve/keyframe.h
  function namespace (line 9) | namespace openage::curve {

FILE: libopenage/curve/keyframe_container.cpp
  type openage::curve (line 5) | namespace openage::curve {

FILE: libopenage/curve/keyframe_container.h
  function namespace (line 15) | namespace openage::curve {

FILE: libopenage/curve/segmented.cpp
  type openage::curve (line 5) | namespace openage::curve {

FILE: libopenage/curve/segmented.h
  function namespace (line 12) | namespace openage::curve {

FILE: libopenage/curve/tests/container.cpp
  type openage::curve::tests (line 22) | namespace openage::curve::tests {
    type map_test_element (line 24) | struct map_test_element {
      method map_test_element (line 27) | explicit map_test_element(int v) :
    function dump (line 41) | void dump(const std::unordered_map<key_t, val_t> &map) {
    function test_map (line 47) | void test_map() {
    function test_list (line 141) | void test_list() {
    function test_queue (line 144) | void test_queue() {
    function test_array (line 246) | void test_array() {
    function container (line 350) | void container() {

FILE: libopenage/curve/tests/curve_types.cpp
  type openage::curve::tests (line 19) | namespace openage::curve::tests {
    function curve_types (line 21) | void curve_types() {

FILE: libopenage/cvar/cvar.cpp
  type openage (line 8) | namespace openage {
    type cvar (line 9) | namespace cvar {

FILE: libopenage/cvar/cvar.h
  function namespace (line 18) | namespace openage {

FILE: libopenage/datastructure/constexpr_map.h
  function namespace (line 12) | namespace openage::datastructure {

FILE: libopenage/datastructure/pairing_heap.h
  function namespace (line 32) | namespace openage::datastructure {
  function element_t (line 382) | element_t push(const T &item) {
  function element_t (line 392) | element_t push(T &&item) {
  function throw (line 406) | throw Error{MSG(err) << "Can't pop an empty heap!"};
  function throw (line 472) | throw Error{ERR << "didn't remove node"};
  function decrease (line 512) | void decrease(const element_t &node) {
  function update (line 529) | void update(element_t &node) {
  function T (line 548) | T remove_node(const element_t &node) {
  function throw (line 682) | throw Error{ERR << "child reencountered when walking forward"};
  function throw (line 691) | throw Error{ERR << "tree invariant violated"};
  function throw (line 708) | throw Error{ERR << "child reencountered when walking back"};
  function throw (line 719) | throw Error{ERR << "node not found as parent's child at all"};
  function else (line 721) | else if (not foundvianext) {
  function push_node (line 817) | void push_node(const element_t &node) {

FILE: libopenage/datastructure/tests.cpp
  type openage::datastructure::tests (line 17) | namespace openage::datastructure::tests {
    function pairing_heap_0 (line 20) | void pairing_heap_0() {
    function pairing_heap_1 (line 67) | void pairing_heap_1() {
    function pairing_heap_2 (line 114) | void pairing_heap_2() {
    function pairing_heap_3 (line 130) | void pairing_heap_3() {
    function pairing_heap (line 156) | void pairing_heap() {
    function constexpr_map (line 165) | void constexpr_map() {
    class MoveOnly (line 217) | class MoveOnly {
      method release (line 221) | int release() {
      method MoveOnly (line 228) | MoveOnly(int data) :
      method MoveOnly (line 230) | MoveOnly(const MoveOnly &) = delete;
      method MoveOnly (line 231) | MoveOnly(MoveOnly &&other) :
      method get (line 235) | int get() const {
    class CopyOnly (line 243) | class CopyOnly {
      method CopyOnly (line 248) | CopyOnly(int data) :
      method CopyOnly (line 250) | CopyOnly(const CopyOnly &other) :
      method CopyOnly (line 252) | CopyOnly(CopyOnly &&) = delete;
      method get (line 255) | int get() const {
    class CopyMove (line 263) | class CopyMove {
      method release (line 270) | int release() {
      method atomic_inc (line 276) | void atomic_inc() {
      method CopyMove (line 282) | CopyMove(int data) :
      method CopyMove (line 287) | CopyMove(const CopyMove &other) :
      method CopyMove (line 293) | CopyMove(CopyMove &&other) :
      method get (line 298) | int get() const {
      method get_accumulated_construction_counter (line 302) | static int get_accumulated_construction_counter() {
      method reset_accumulated_construction_counter (line 306) | static void reset_accumulated_construction_counter() {
    function concurrent_queue_copy_only_elements_compilation (line 314) | void concurrent_queue_copy_only_elements_compilation() {
    function concurrent_queue_move_only_elements_compilation (line 327) | void concurrent_queue_move_only_elements_compilation() {
    function concurrent_queue_copy_move_elements_compilation (line 340) | void concurrent_queue_copy_move_elements_compilation() {
    function concurrent_queue (line 358) | void concurrent_queue() {

FILE: libopenage/datastructure/tests.h
  function namespace (line 9) | namespace openage::datastructure::tests {
  function namespace (line 28) | namespace std {

FILE: libopenage/engine/engine.cpp
  type openage::engine (line 14) | namespace openage::engine {

FILE: libopenage/engine/engine.h
  function namespace (line 17) | namespace std {
  function namespace (line 38) | namespace openage {

FILE: libopenage/error/backtrace.cpp
  type openage (line 9) | namespace openage {
    type error (line 10) | namespace error {

FILE: libopenage/error/backtrace.h
  function namespace (line 14) | namespace openage {

FILE: libopenage/error/demo.cpp
  type openage::error (line 11) | namespace openage::error {
    function foo (line 18) | void foo() {
    function bar (line 23) | void bar(int i) {
    function demo (line 46) | void demo() {

FILE: libopenage/error/error.cpp
  type openage::error (line 12) | namespace openage::error {

FILE: libopenage/error/error.h
  function namespace (line 19) | namespace openage {
  function namespace (line 26) | namespace openage {
  function namespace (line 34) | namespace openage {

FILE: libopenage/error/handlers.cpp
  type openage (line 33) | namespace openage {
    type error (line 34) | namespace error {
      function terminate_handler (line 69) | [[noreturn]] void terminate_handler() noexcept {
      function sigsegv_handler (line 110) | void sigsegv_handler(int /* unused */) {
      function exit_handler (line 122) | void exit_handler() {
      function set_exit_ok (line 140) | void set_exit_ok(bool value) {

FILE: libopenage/error/handlers.h
  function namespace (line 8) | namespace openage {

FILE: libopenage/error/stackanalyzer.cpp
  type openage::error (line 14) | namespace openage::error {
  type openage (line 36) | namespace openage {
    type error (line 37) | namespace error {
      type info_cb_data_t (line 44) | struct info_cb_data_t {
      function backtrace_error_callback (line 51) | void backtrace_error_callback(void * /*unused*/, const char *msg, in...
      type backtrace_state (line 56) | struct backtrace_state
      function backtrace_simple_callback (line 72) | int backtrace_simple_callback(void *data, uintptr_t pc) {
      function backtrace_syminfo_callback (line 80) | void backtrace_syminfo_callback(
      function backtrace_pcinfo_callback (line 100) | int backtrace_pcinfo_callback(void *data, uintptr_t pc, const char *...
      function backtrace_pcinfo_error_callback (line 125) | void backtrace_pcinfo_error_callback(void *data, const char *msg, in...
    type error (line 196) | namespace error {
      type info_cb_data_t (line 44) | struct info_cb_data_t {
      function backtrace_error_callback (line 51) | void backtrace_error_callback(void * /*unused*/, const char *msg, in...
      type backtrace_state (line 56) | struct backtrace_state
      function backtrace_simple_callback (line 72) | int backtrace_simple_callback(void *data, uintptr_t pc) {
      function backtrace_syminfo_callback (line 80) | void backtrace_syminfo_callback(
      function backtrace_pcinfo_callback (line 100) | int backtrace_pcinfo_callback(void *data, uintptr_t pc, const char *...
      function backtrace_pcinfo_error_callback (line 125) | void backtrace_pcinfo_error_callback(void *data, const char *msg, in...
  type openage (line 195) | namespace openage {
    type error (line 37) | namespace error {
      type info_cb_data_t (line 44) | struct info_cb_data_t {
      function backtrace_error_callback (line 51) | void backtrace_error_callback(void * /*unused*/, const char *msg, in...
      type backtrace_state (line 56) | struct backtrace_state
      function backtrace_simple_callback (line 72) | int backtrace_simple_callback(void *data, uintptr_t pc) {
      function backtrace_syminfo_callback (line 80) | void backtrace_syminfo_callback(
      function backtrace_pcinfo_callback (line 100) | int backtrace_pcinfo_callback(void *data, uintptr_t pc, const char *...
      function backtrace_pcinfo_error_callback (line 125) | void backtrace_pcinfo_error_callback(void *data, const char *msg, in...
    type error (line 196) | namespace error {
      type info_cb_data_t (line 44) | struct info_cb_data_t {
      function backtrace_error_callback (line 51) | void backtrace_error_callback(void * /*unused*/, const char *msg, in...
      type backtrace_state (line 56) | struct backtrace_state
      function backtrace_simple_callback (line 72) | int backtrace_simple_callback(void *data, uintptr_t pc) {
      function backtrace_syminfo_callback (line 80) | void backtrace_syminfo_callback(
      function backtrace_pcinfo_callback (line 100) | int backtrace_pcinfo_callback(void *data, uintptr_t pc, const char *...
      function backtrace_pcinfo_error_callback (line 125) | void backtrace_pcinfo_error_callback(void *data, const char *msg, in...
  type openage::error (line 216) | namespace openage::error {
  type openage::error (line 261) | namespace openage::error {
  type openage::error (line 297) | namespace openage::error {

FILE: libopenage/error/stackanalyzer.h
  function namespace (line 11) | namespace openage {

FILE: libopenage/event/demo/aicontroller.cpp
  type openage::event::demo (line 5) | namespace openage::event::demo {
    function get_ai_inputs (line 7) | std::vector<PongEvent> get_ai_inputs(const std::shared_ptr<PongPlayer>...

FILE: libopenage/event/demo/aicontroller.h
  function namespace (line 9) | namespace openage::event::demo {

FILE: libopenage/event/demo/gamestate.cpp
  type openage::event::demo (line 5) | namespace openage::event::demo {

FILE: libopenage/event/demo/gamestate.h
  function namespace (line 23) | namespace openage::event {

FILE: libopenage/event/demo/gui.cpp
  type openage::event::demo (line 24) | namespace openage::event::demo {

FILE: libopenage/event/demo/gui.h
  function namespace (line 18) | namespace openage::event::demo {

FILE: libopenage/event/demo/main.cpp
  type openage::event::demo (line 31) | namespace openage::event::demo {
    type timescale (line 36) | enum class timescale {
    function curvepong (line 44) | void curvepong(bool disable_gui, bool no_human) {

FILE: libopenage/event/demo/main.h
  function namespace (line 9) | namespace openage::event::demo {

FILE: libopenage/event/demo/physics.cpp
  class BallReflectWall (line 45) | class BallReflectWall : public DependencyEventHandler {
    method BallReflectWall (line 47) | BallReflectWall() :
    method setup_event (line 50) | void setup_event(const std::shared_ptr<Event> &evnt,
    method invoke (line 64) | void invoke(EventLoop &,
    method predict_invoke_time (line 97) | time::time_t predict_invoke_time(const std::shared_ptr<EventEntity> &t...
  function BallReflectPanel (line 135) | BallReflectPanel() :
  function setup_event (line 138) | void setup_event(const std::shared_ptr<Event> &target,
  function ResetGame (line 272) | ResetGame() :
  function setup_event (line 275) | void setup_event(const std::shared_ptr<Event> & /*target*/,
  function invoke (line 278) | void invoke(EventLoop & /*mgr*/,

FILE: libopenage/event/demo/physics.h
  function namespace (line 11) | namespace openage::event {

FILE: libopenage/event/event.cpp
  type openage::event (line 19) | namespace openage::event {

FILE: libopenage/event/event.h
  function namespace (line 12) | namespace openage::event {

FILE: libopenage/event/event_loop.cpp
  type openage::event (line 22) | namespace openage::event {

FILE: libopenage/event/event_loop.h
  function namespace (line 15) | namespace openage::event {

FILE: libopenage/event/evententity.cpp
  type openage::event (line 16) | namespace openage::event {

FILE: libopenage/event/eventhandler.cpp
  type openage::event (line 5) | namespace openage::event {

FILE: libopenage/event/eventhandler.h
  function namespace (line 16) | namespace openage::event {

FILE: libopenage/event/eventqueue.cpp
  type openage::event (line 20) | namespace openage::event {
    function EventStore (line 159) | const EventStore &EventQueue::get_event_queue() const {

FILE: libopenage/event/eventqueue.h
  function namespace (line 14) | namespace openage::event {

FILE: libopenage/event/eventstore.cpp
  type openage::event (line 14) | namespace openage::event {

FILE: libopenage/event/eventstore.h
  function namespace (line 15) | namespace openage::event {

FILE: libopenage/event/state.cpp
  type openage::event (line 5) | namespace openage::event {

FILE: libopenage/event/state.h
  function namespace (line 8) | namespace openage::event {

FILE: libopenage/event/tests.cpp
  type openage::event::tests (line 25) | namespace openage::event::tests {
    class TestState (line 28) | class TestState : public State {
      class TestObject (line 30) | class TestObject : public EventEntity {
        method TestObject (line 34) | TestObject(const std::shared_ptr<EventLoop> &loop, int id) :
        method set_number (line 39) | void set_number(int number, const time::time_t &time) {
        method id (line 44) | [[nodiscard]] size_t id() const override {
        method idstr (line 48) | std::string idstr() const override {
        method test_trigger (line 54) | void test_trigger(const time::time_t &time) {
      method TestState (line 61) | explicit TestState(const std::shared_ptr<EventLoop> &loop) :
      type traceelement (line 69) | struct traceelement {
        method traceelement (line 70) | traceelement(std::string event, time::time_t time) :
      method log_dbg (line 80) | void log_dbg() {
    class TestEventHandler (line 89) | class TestEventHandler : public EventHandler {
      method TestEventHandler (line 93) | TestEventHandler(const std::string &name, int idx) :
      method setup_event (line 97) | void setup_event(const std::shared_ptr<Event> &event,
      method invoke (line 113) | void invoke(EventLoop & /*loop*/,
      method predict_invoke_time (line 137) | time::time_t predict_invoke_time(const std::shared_ptr<EventEntity> ...
    class TestEventHandlerTwo (line 145) | class TestEventHandlerTwo : public EventHandler {
      method TestEventHandlerTwo (line 147) | explicit TestEventHandlerTwo(const std::string &name) :
      method setup_event (line 150) | void setup_event(const std::shared_ptr<Event> &target,
      method invoke (line 156) | void invoke(EventLoop & /*loop*/,
      method predict_invoke_time (line 169) | time::time_t predict_invoke_time(const std::shared_ptr<EventEntity> ...
    class EventTypeTestClass (line 178) | class EventTypeTestClass : public EventHandler {
      method EventTypeTestClass (line 180) | EventTypeTestClass(const std::string &name, EventHandler::trigger_ty...
      method setup_event (line 183) | void setup_event(const std::shared_ptr<Event> &event,
      method invoke (line 192) | void invoke(EventLoop & /*loop*/,
      method predict_invoke_time (line 206) | time::time_t predict_invoke_time(const std::shared_ptr<EventEntity> ...
    function eventtrigger (line 234) | void eventtrigger() {

FILE: libopenage/gamestate/activity/activity.cpp
  type openage::gamestate::activity (line 6) | namespace openage::gamestate::activity {
    function activity_id (line 16) | activity_id Activity::get_id() const {
    function activity_label (line 20) | const activity_label Activity::get_label() const {

FILE: libopenage/gamestate/activity/activity.h
  function namespace (line 10) | namespace openage::gamestate::activity {

FILE: libopenage/gamestate/activity/condition/command_in_queue.cpp
  type openage::gamestate::activity (line 9) | namespace openage::gamestate::activity {
    function command_in_queue (line 11) | bool command_in_queue(const time::time_t &time,

FILE: libopenage/gamestate/activity/condition/command_in_queue.h
  function namespace (line 11) | namespace openage::gamestate {

FILE: libopenage/gamestate/activity/condition/next_command.cpp
  type openage::gamestate::activity (line 9) | namespace openage::gamestate::activity {
    function next_command_idle (line 11) | bool next_command_idle(const time::time_t &time,
    function next_command_move (line 24) | bool next_command_move(const time::time_t &time,

FILE: libopenage/gamestate/activity/condition/next_command.h
  function namespace (line 11) | namespace openage::gamestate {

FILE: libopenage/gamestate/activity/end_node.cpp
  type openage::gamestate::activity (line 9) | namespace openage::gamestate::activity {

FILE: libopenage/gamestate/activity/end_node.h
  function namespace (line 11) | namespace openage::gamestate::activity {

FILE: libopenage/gamestate/activity/event/command_in_queue.cpp
  type openage::gamestate::activity (line 13) | namespace openage::gamestate::activity {
    function primer_command_in_queue (line 15) | std::shared_ptr<openage::event::Event> primer_command_in_queue(const t...

FILE: libopenage/gamestate/activity/event/command_in_queue.h
  function namespace (line 11) | namespace openage {

FILE: libopenage/gamestate/activity/event/wait.cpp
  type openage::gamestate::activity (line 12) | namespace openage::gamestate::activity {
    function primer_wait (line 14) | std::shared_ptr<openage::event::Event> primer_wait(const time::time_t ...

FILE: libopenage/gamestate/activity/event/wait.h
  function namespace (line 11) | namespace openage {

FILE: libopenage/gamestate/activity/node.cpp
  type openage::gamestate::activity (line 11) | namespace openage::gamestate::activity {
    function node_id_t (line 25) | node_id_t Node::get_id() const {
    function node_label_t (line 29) | const node_label_t Node::get_label() const {

FILE: libopenage/gamestate/activity/node.h
  function namespace (line 14) | namespace openage::gamestate::activity {

FILE: libopenage/gamestate/activity/start_node.cpp
  type openage::gamestate::activity (line 9) | namespace openage::gamestate::activity {
    function node_id_t (line 25) | node_id_t StartNode::get_next() const {

FILE: libopenage/gamestate/activity/start_node.h
  function namespace (line 11) | namespace openage::gamestate::activity {

FILE: libopenage/gamestate/activity/task_node.cpp
  type openage::gamestate::activity (line 9) | namespace openage::gamestate::activity {
    function task_func_t (line 31) | task_func_t TaskCustom::get_task_func() const {
    function node_id_t (line 35) | node_id_t TaskCustom::get_next() const {

FILE: libopenage/gamestate/activity/task_node.h
  function namespace (line 16) | namespace openage::gamestate {

FILE: libopenage/gamestate/activity/task_system_node.cpp
  type openage::gamestate::activity (line 9) | namespace openage::gamestate::activity {
    function node_id_t (line 35) | node_id_t TaskSystemNode::get_next() const {

FILE: libopenage/gamestate/activity/task_system_node.h
  function namespace (line 12) | namespace openage::gamestate::activity {

FILE: libopenage/gamestate/activity/tests.cpp
  type openage::gamestate::tests (line 27) | namespace openage::gamestate::tests {
    class TestActivityManager (line 45) | class TestActivityManager : public event::EventEntity {
      method TestActivityManager (line 47) | TestActivityManager(const std::shared_ptr<event::EventLoop> &loop,
      method id (line 53) | size_t id() const override {
      method idstr (line 57) | std::string idstr() const override {
      method run (line 61) | void run(const std::optional<event::EventHandler::param_map> ev_para...
    class TestActivityState (line 74) | class TestActivityState : public event::State {
    class TestActivityHandler (line 84) | class TestActivityHandler : public event::OnceEventHandler {
      method setup_event (line 88) | void setup_event(const std::shared_ptr<event::Event> & /* event */,
      method invoke (line 93) | void invoke(event::EventLoop & /* loop */,
      method predict_invoke_time (line 102) | time::time_t predict_invoke_time(const std::shared_ptr<event::EventE...
    function activity_flow (line 110) | const std::shared_ptr<activity::Node> activity_flow(const std::shared_...
    function activity_demo (line 202) | void activity_demo() {

FILE: libopenage/gamestate/activity/types.cpp
  type openage::gamestate::activity (line 6) | namespace openage::gamestate::activity {

FILE: libopenage/gamestate/activity/types.h
  function namespace (line 6) | namespace openage::gamestate::activity {

FILE: libopenage/gamestate/activity/xor_event_gate.cpp
  type openage::gamestate::activity (line 8) | namespace openage::gamestate::activity {

FILE: libopenage/gamestate/activity/xor_event_gate.h
  function namespace (line 18) | namespace openage {

FILE: libopenage/gamestate/activity/xor_gate.cpp
  type openage::gamestate::activity (line 8) | namespace openage::gamestate::activity {

FILE: libopenage/gamestate/activity/xor_gate.h
  function namespace (line 19) | namespace openage::gamestate {

FILE: libopenage/gamestate/api/ability.cpp
  type openage::gamestate::api (line 16) | namespace openage::gamestate::api {

FILE: libopenage/gamestate/api/ability.h
  function namespace (line 9) | namespace openage::gamestate::api {

FILE: libopenage/gamestate/api/activity.cpp
  type openage::gamestate::api (line 8) | namespace openage::gamestate::api {

FILE: libopenage/gamestate/api/activity.h
  function namespace (line 15) | namespace openage::gamestate {

FILE: libopenage/gamestate/api/animation.cpp
  type openage::gamestate::api (line 10) | namespace openage::gamestate::api {

FILE: libopenage/gamestate/api/animation.h
  function namespace (line 11) | namespace openage::gamestate::api {

FILE: libopenage/gamestate/api/definitions.cpp
  type openage::gamestate::api (line 5) | namespace openage::gamestate::api {

FILE: libopenage/gamestate/api/definitions.h
  function namespace (line 22) | namespace openage::gamestate::api {

FILE: libopenage/gamestate/api/patch.cpp
  type openage::gamestate::api (line 16) | namespace openage::gamestate::api {

FILE: libopenage/gamestate/api/patch.h
  function namespace (line 10) | namespace openage::gamestate::api {

FILE: libopenage/gamestate/api/player_setup.cpp
  type openage::gamestate::api (line 13) | namespace openage::gamestate::api {

FILE: libopenage/gamestate/api/player_setup.h
  function namespace (line 10) | namespace openage::gamestate::api {

FILE: libopenage/gamestate/api/property.cpp
  type openage::gamestate::api (line 13) | namespace openage::gamestate::api {

FILE: libopenage/gamestate/api/property.h
  function namespace (line 10) | namespace openage::gamestate::api {

FILE: libopenage/gamestate/api/sound.cpp
  type openage::gamestate::api (line 12) | namespace openage::gamestate::api {

FILE: libopenage/gamestate/api/sound.h
  function namespace (line 11) | namespace openage::gamestate::api {

FILE: libopenage/gamestate/api/terrain.cpp
  type openage::gamestate::api (line 10) | namespace openage::gamestate::api {

FILE: libopenage/gamestate/api/terrain.h
  function namespace (line 10) | namespace openage::gamestate::api {

FILE: libopenage/gamestate/api/types.cpp
  type openage::gamestate::api (line 5) | namespace openage::gamestate::api {

FILE: libopenage/gamestate/api/types.h
  type class (line 11) | enum class
  function ability_property_t (line 23) | enum class ability_property_t {

FILE: libopenage/gamestate/api/util.cpp
  type openage::gamestate::api (line 14) | namespace openage::gamestate::api {
    function resolve_file_path (line 16) | const std::string resolve_file_path(const nyan::Object &obj, const std...

FILE: libopenage/gamestate/api/util.h
  function namespace (line 10) | namespace openage::gamestate::api {

FILE: libopenage/gamestate/component/api/idle.cpp
  type openage::gamestate::component (line 7) | namespace openage::gamestate::component {
    function component_t (line 9) | component_t Idle::get_type() const {

FILE: libopenage/gamestate/component/api/idle.h
  function namespace (line 8) | namespace openage::gamestate::component {

FILE: libopenage/gamestate/component/api/live.cpp
  type openage::gamestate::component (line 13) | namespace openage::gamestate::component {
    function component_t (line 15) | component_t Live::get_type() const {

FILE: libopenage/gamestate/component/api/live.h
  function namespace (line 16) | namespace openage::gamestate::component {

FILE: libopenage/gamestate/component/api/move.cpp
  type openage::gamestate::component (line 8) | namespace openage::gamestate::component {
    function component_t (line 10) | component_t Move::get_type() const {

FILE: libopenage/gamestate/component/api/move.h
  function namespace (line 9) | namespace openage::gamestate::component {

FILE: libopenage/gamestate/component/api/selectable.cpp
  type openage::gamestate::component (line 6) | namespace openage::gamestate::component {
    function component_t (line 8) | component_t Selectable::get_type() const {

FILE: libopenage/gamestate/component/api/selectable.h
  function namespace (line 11) | namespace openage::gamestate::component {

FILE: libopenage/gamestate/component/api/turn.cpp
  type openage::gamestate::component (line 8) | namespace openage::gamestate::component {
    function component_t (line 10) | component_t Turn::get_type() const {

FILE: libopenage/gamestate/component/api/turn.h
  function namespace (line 11) | namespace openage::gamestate::component {

FILE: libopenage/gamestate/component/api_component.cpp
  type openage::gamestate::component (line 6) | namespace openage::gamestate::component {

FILE: libopenage/gamestate/component/api_component.h
  function namespace (line 14) | namespace openage {

FILE: libopenage/gamestate/component/base_component.cpp
  type openage::gamestate::component (line 5) | namespace openage::gamestate::component {

FILE: libopenage/gamestate/component/base_component.h
  function namespace (line 7) | namespace openage::gamestate::component {

FILE: libopenage/gamestate/component/internal/activity.cpp
  type openage::gamestate::component (line 10) | namespace openage::gamestate::component {
    function component_t (line 18) | component_t Activity::get_type() const {

FILE: libopenage/gamestate/component/internal/activity.h
  function namespace (line 14) | namespace openage {

FILE: libopenage/gamestate/component/internal/command_queue.cpp
  type openage::gamestate::component (line 10) | namespace openage::gamestate::component {
    function component_t (line 16) | inline component_t CommandQueue::get_type() const {

FILE: libopenage/gamestate/component/internal/command_queue.h
  function namespace (line 14) | namespace openage {

FILE: libopenage/gamestate/component/internal/commands/base_command.h
  function namespace (line 8) | namespace openage::gamestate::component::command {

FILE: libopenage/gamestate/component/internal/commands/custom.cpp
  type openage::gamestate::component::command (line 6) | namespace openage::gamestate::component::command {

FILE: libopenage/gamestate/component/internal/commands/custom.h
  function namespace (line 11) | namespace openage::gamestate::component::command {

FILE: libopenage/gamestate/component/internal/commands/idle.cpp
  type openage::gamestate::component::command (line 6) | namespace openage::gamestate::component::command {

FILE: libopenage/gamestate/component/internal/commands/idle.h
  function namespace (line 9) | namespace openage::gamestate::component::command {

FILE: libopenage/gamestate/component/internal/commands/move.cpp
  type openage::gamestate::component::command (line 6) | namespace openage::gamestate::component::command {

FILE: libopenage/gamestate/component/internal/commands/move.h
  function namespace (line 10) | namespace openage::gamestate::component::command {

FILE: libopenage/gamestate/component/internal/commands/types.cpp
  type openage::gamestate::component::command (line 6) | namespace openage::gamestate::component::command {

FILE: libopenage/gamestate/component/internal/commands/types.h
  function namespace (line 6) | namespace openage::gamestate::component::command {

FILE: libopenage/gamestate/component/internal/ownership.cpp
  type openage::gamestate::component (line 8) | namespace openage::gamestate::component {
    function component_t (line 21) | inline component_t Ownership::get_type() const {

FILE: libopenage/gamestate/component/internal/ownership.h
  function namespace (line 15) | namespace openage {

FILE: libopenage/gamestate/component/internal/position.cpp
  type openage::gamestate::component (line 10) | namespace openage::gamestate::component {
    function component_t (line 45) | inline component_t Position::get_type() const {

FILE: libopenage/gamestate/component/internal/position.h
  function namespace (line 16) | namespace openage {

FILE: libopenage/gamestate/component/internal_component.cpp
  type openage::gamestate::component (line 5) | namespace openage::gamestate::component {

FILE: libopenage/gamestate/component/internal_component.h
  function namespace (line 7) | namespace openage::gamestate::component {

FILE: libopenage/gamestate/component/types.cpp
  type openage::gamestate::component (line 5) | namespace openage::gamestate::component {

FILE: libopenage/gamestate/component/types.h
  function namespace (line 6) | namespace openage::gamestate::component {

FILE: libopenage/gamestate/definitions.cpp
  type openage::gamestate (line 5) | namespace openage::gamestate {

FILE: libopenage/gamestate/definitions.h
  function namespace (line 12) | namespace openage::gamestate {

FILE: libopenage/gamestate/demo/demo_0.cpp
  type openage::gamestate::tests (line 10) | namespace openage::gamestate::tests {
    function simulation_demo_0 (line 12) | void simulation_demo_0(const util::Path &path) {

FILE: libopenage/gamestate/demo/demo_0.h
  function namespace (line 8) | namespace openage::gamestate::tests {

FILE: libopenage/gamestate/demo/tests.cpp
  type openage::gamestate::tests (line 11) | namespace openage::gamestate::tests {
    function simulation_demo (line 13) | void simulation_demo(int demo_id, const util::Path &path) {

FILE: libopenage/gamestate/demo/tests.h
  function namespace (line 9) | namespace openage {

FILE: libopenage/gamestate/entity_factory.cpp
  type openage::gamestate (line 46) | namespace openage::gamestate {
    function create_test_activity (line 60) | std::shared_ptr<activity::Activity> create_test_activity() {
    function entity_id_t (line 361) | entity_id_t EntityFactory::get_next_entity_id() {
    function player_id_t (line 368) | player_id_t EntityFactory::get_next_player_id() {

FILE: libopenage/gamestate/entity_factory.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/gamestate/event/drag_select.cpp
  type openage::gamestate::event (line 18) | namespace openage::gamestate::event {

FILE: libopenage/gamestate/event/drag_select.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/gamestate/event/process_command.cpp
  type openage::gamestate::event (line 8) | namespace openage::gamestate::event {

FILE: libopenage/gamestate/event/process_command.h
  function namespace (line 11) | namespace openage {

FILE: libopenage/gamestate/event/send_command.cpp
  type openage::gamestate (line 17) | namespace openage::gamestate {
    type component (line 18) | namespace component {
      class CommandQueue (line 19) | class CommandQueue
      type command (line 21) | namespace command {
        class IdleCommand (line 22) | class IdleCommand
        class MoveCommand (line 23) | class MoveCommand
    type event (line 27) | namespace event {

FILE: libopenage/gamestate/event/send_command.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/gamestate/event/spawn_entity.cpp
  type openage::gamestate::event (line 28) | namespace openage::gamestate::event {
    function build_test_entities (line 85) | void build_test_entities(const std::shared_ptr<GameState> &gstate) {

FILE: libopenage/gamestate/event/spawn_entity.h
  function namespace (line 14) | namespace openage {

FILE: libopenage/gamestate/event/wait.cpp
  type openage::gamestate::event (line 8) | namespace openage::gamestate::event {

FILE: libopenage/gamestate/event/wait.h
  function namespace (line 11) | namespace openage {

FILE: libopenage/gamestate/game.cpp
  type openage::gamestate (line 25) | namespace openage::gamestate {

FILE: libopenage/gamestate/game.h
  function namespace (line 8) | namespace nyan {
  function namespace (line 12) | namespace openage {

FILE: libopenage/gamestate/game_entity.cpp
  type openage::gamestate (line 14) | namespace openage::gamestate {
    function entity_id_t (line 29) | entity_id_t GameEntity::get_id() const {

FILE: libopenage/gamestate/game_entity.h
  function namespace (line 14) | namespace openage {

FILE: libopenage/gamestate/game_state.cpp
  type openage::gamestate (line 14) | namespace openage::gamestate {

FILE: libopenage/gamestate/game_state.h
  function namespace (line 12) | namespace nyan {
  function namespace (line 17) | namespace openage {

FILE: libopenage/gamestate/manager.cpp
  type openage::gamestate (line 13) | namespace openage::gamestate {

FILE: libopenage/gamestate/manager.h
  function namespace (line 15) | namespace openage {

FILE: libopenage/gamestate/map.cpp
  type openage::gamestate (line 17) | namespace openage::gamestate {

FILE: libopenage/gamestate/map.h
  function namespace (line 14) | namespace openage {

FILE: libopenage/gamestate/player.cpp
  type openage::gamestate (line 8) | namespace openage::gamestate {
    function player_id_t (line 23) | player_id_t Player::get_id() const {

FILE: libopenage/gamestate/player.h
  function namespace (line 10) | namespace nyan {
  function namespace (line 14) | namespace openage::gamestate {

FILE: libopenage/gamestate/simulation.cpp
  type openage::gamestate (line 21) | namespace openage::gamestate {

FILE: libopenage/gamestate/simulation.h
  function namespace (line 9) | namespace openage {

FILE: libopenage/gamestate/system/activity.cpp
  type openage::gamestate::system (line 27) | namespace openage::gamestate::system {

FILE: libopenage/gamestate/system/activity.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/gamestate/system/idle.cpp
  type openage::gamestate::system (line 20) | namespace openage::gamestate::system {

FILE: libopenage/gamestate/system/idle.h
  function namespace (line 10) | namespace openage::gamestate {

FILE: libopenage/gamestate/system/move.cpp
  type openage::gamestate::system (line 34) | namespace openage::gamestate::system {
    function find_path (line 37) | std::vector<coord::phys3> find_path(const std::shared_ptr<path::Pathfi...

FILE: libopenage/gamestate/system/move.h
  function namespace (line 11) | namespace openage::gamestate {

FILE: libopenage/gamestate/system/types.cpp
  type openage::gamestate::system (line 6) | namespace openage::gamestate::system {

FILE: libopenage/gamestate/system/types.h
  function namespace (line 6) | namespace openage::gamestate::system {

FILE: libopenage/gamestate/terrain.cpp
  type openage::gamestate (line 15) | namespace openage::gamestate {

FILE: libopenage/gamestate/terrain.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/gamestate/terrain_chunk.cpp
  type openage::gamestate (line 6) | namespace openage::gamestate {
    function TerrainTile (line 37) | const TerrainTile &TerrainChunk::get_tile(size_t idx) const {
    function TerrainTile (line 41) | const TerrainTile &TerrainChunk::get_tile(const coord::tile &pos) const {

FILE: libopenage/gamestate/terrain_chunk.h
  function namespace (line 14) | namespace openage::gamestate {

FILE: libopenage/gamestate/terrain_factory.cpp
  type openage::gamestate (line 21) | namespace openage::gamestate {
    function build_test_terrains (line 76) | void build_test_terrains(const std::shared_ptr<GameState> &gstate) {

FILE: libopenage/gamestate/terrain_factory.h
  function namespace (line 12) | namespace openage {

FILE: libopenage/gamestate/terrain_tile.cpp
  type openage::gamestate (line 6) | namespace openage::gamestate {

FILE: libopenage/gamestate/terrain_tile.h
  function namespace (line 13) | namespace openage::gamestate {

FILE: libopenage/gamestate/types.cpp
  type openage::gamestate (line 5) | namespace openage::gamestate {

FILE: libopenage/gamestate/types.h
  function namespace (line 7) | namespace openage::gamestate {

FILE: libopenage/gamestate/universe.cpp
  type openage::gamestate (line 9) | namespace openage::gamestate {

FILE: libopenage/gamestate/universe.h
  function namespace (line 7) | namespace openage {

FILE: libopenage/gamestate/world.cpp
  type openage::gamestate (line 13) | namespace openage::gamestate {

FILE: libopenage/gamestate/world.h
  function namespace (line 8) | namespace openage {

FILE: libopenage/input/action.cpp
  type openage::input (line 5) | namespace openage::input {

FILE: libopenage/input/action.h
  function namespace (line 10) | namespace openage::input {

FILE: libopenage/input/controller/camera/binding.cpp
  type openage::input::camera (line 5) | namespace openage::input::camera {

FILE: libopenage/input/controller/camera/binding.h
  function namespace (line 11) | namespace openage::input::camera {

FILE: libopenage/input/controller/camera/binding_context.cpp
  type openage::input::camera (line 6) | namespace openage::input::camera {
    function binding_action (line 23) | const binding_action &BindingContext::lookup(const Event &ev) const {

FILE: libopenage/input/controller/camera/binding_context.h
  function namespace (line 10) | namespace openage::input::camera {

FILE: libopenage/input/controller/camera/controller.cpp
  type openage::input::camera (line 11) | namespace openage::input::camera {
    function setup_defaults (line 27) | void setup_defaults(const std::shared_ptr<BindingContext> &ctx,

FILE: libopenage/input/controller/camera/controller.h
  function namespace (line 10) | namespace openage {

FILE: libopenage/input/controller/game/binding.cpp
  type openage::input::game (line 5) | namespace openage::input::game {

FILE: libopenage/input/controller/game/binding.h
  function namespace (line 12) | namespace openage::input::game {

FILE: libopenage/input/controller/game/binding_context.cpp
  type openage::input::game (line 6) | namespace openage::input::game {
    function binding_action (line 23) | const binding_action &BindingContext::lookup(const Event &ev) const {

FILE: libopenage/input/controller/game/binding_context.h
  function namespace (line 10) | namespace openage::input::game {

FILE: libopenage/input/controller/game/controller.cpp
  type openage::input::game (line 24) | namespace openage::input::game {
    function setup_defaults (line 119) | void setup_defaults(const std::shared_ptr<BindingContext> &ctx,

FILE: libopenage/input/controller/game/controller.h
  function namespace (line 16) | namespace openage {

FILE: libopenage/input/controller/hud/binding.cpp
  type openage::input::hud (line 5) | namespace openage::input::hud {

FILE: libopenage/input/controller/hud/binding.h
  function namespace (line 11) | namespace openage::input::hud {

FILE: libopenage/input/controller/hud/binding_context.cpp
  type openage::input::hud (line 6) | namespace openage::input::hud {
    function binding_action (line 23) | const binding_action &BindingContext::lookup(const Event &ev) const {

FILE: libopenage/input/controller/hud/binding_context.h
  function namespace (line 10) | namespace openage::input::hud {

FILE: libopenage/input/controller/hud/controller.cpp
  type openage::input::hud (line 13) | namespace openage::input::hud {
    function setup_defaults (line 38) | void setup_defaults(const std::shared_ptr<BindingContext> &ctx,

FILE: libopenage/input/controller/hud/controller.h
  function namespace (line 10) | namespace openage {

FILE: libopenage/input/event.cpp
  type openage::input (line 8) | namespace openage::input {

FILE: libopenage/input/event.h
  function event_class (line 22) | enum class event_class {

FILE: libopenage/input/input_context.cpp
  type openage::input (line 6) | namespace openage::input {

FILE: libopenage/input/input_context.h
  function namespace (line 11) | namespace openage::input {

FILE: libopenage/input/input_manager.cpp
  type openage::input (line 13) | namespace openage::input {
    function setup_defaults (line 212) | void setup_defaults(const std::shared_ptr<InputContext> &ctx) {

FILE: libopenage/input/input_manager.h
  function namespace (line 15) | namespace qtgui {
  function namespace (line 21) | namespace camera {
  function namespace (line 25) | namespace game {
  function namespace (line 29) | namespace hud {

FILE: libopenage/input/tests.cpp
  type openage::input::tests (line 11) | namespace openage::input::tests {
    function action_demo (line 13) | void action_demo() {

FILE: libopenage/input/text_to_event.cpp
  type openage::input (line 11) | namespace openage::input {
    function Event (line 13) | Event text_to_event(const std::string &event_str) {

FILE: libopenage/input/text_to_event.h
  function namespace (line 9) | namespace openage::input {

FILE: libopenage/job/abortable_job_state.h
  function namespace (line 11) | namespace openage {

FILE: libopenage/job/job.h
  function namespace (line 10) | namespace openage {

FILE: libopenage/job/job_aborted_exception.h
  function namespace (line 7) | namespace openage {

FILE: libopenage/job/job_group.cpp
  type openage::job (line 5) | namespace openage::job {

FILE: libopenage/job/job_group.h
  function namespace (line 14) | namespace openage {

FILE: libopenage/job/job_manager.cpp
  type openage::job (line 10) | namespace openage::job {
    function JobGroup (line 82) | JobGroup JobManager::create_job_group() {

FILE: libopenage/job/job_manager.h
  function namespace (line 20) | namespace openage {

FILE: libopenage/job/job_state.h
  function namespace (line 10) | namespace openage {

FILE: libopenage/job/job_state_base.h
  function namespace (line 9) | namespace openage {

FILE: libopenage/job/tests.cpp
  type openage (line 10) | namespace openage {
    type job (line 11) | namespace job {
      type tests (line 12) | namespace tests {
        function test_simple_job (line 15) | void test_simple_job() {
        function test_simple_job_with_exception (line 49) | void test_simple_job_with_exception() {
        function test_job_manager (line 93) | void test_job_manager() {

FILE: libopenage/job/typed_job_state_base.h
  function execute (line 65) | bool execute(should_abort_t should_abort) override {
  function execute_callback (line 83) | void execute_callback() override {
  function get_thread_id (line 98) | size_t get_thread_id() override {

FILE: libopenage/job/types.h
  function namespace (line 7) | namespace openage {

FILE: libopenage/job/worker.cpp
  type openage (line 10) | namespace openage {
    type job (line 11) | namespace job {

FILE: libopenage/job/worker.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/log/file_logsink.cpp
  type openage::log (line 13) | namespace openage::log {

FILE: libopenage/log/file_logsink.h
  function namespace (line 9) | namespace openage {

FILE: libopenage/log/level.cpp
  type openage (line 5) | namespace openage {
    type log (line 7) | namespace log {

FILE: libopenage/log/level.h
  function level_value (line 21) | struct OAAPI level_value : util::EnumValue<level_value> {
  type OAAPI (line 44) | struct OAAPI
  function level_value (line 69) | static constexpr level_value MAX NOOPTIMIZE{{"max loglevel", 1000}, "5"};

FILE: libopenage/log/log.cpp
  type openage (line 9) | namespace openage {
    type log (line 10) | namespace log {
      function log (line 13) | void log(const message &msg) {
      function set_level (line 18) | void set_level(level lvl) {

FILE: libopenage/log/log.h
  function namespace (line 11) | namespace openage {

FILE: libopenage/log/logsink.cpp
  type openage (line 9) | namespace openage {
    type log (line 10) | namespace log {
      function LogSinkList (line 36) | LogSinkList &LogSinkList::instance() {
      class LogSource (line 42) | class LogSource

FILE: libopenage/log/logsink.h
  function namespace (line 12) | namespace openage::log {

FILE: libopenage/log/logsource.cpp
  type openage (line 13) | namespace openage {
    type log (line 14) | namespace log {

FILE: libopenage/log/logsource.h
  function namespace (line 16) | namespace openage {

FILE: libopenage/log/message.cpp
  type openage (line 18) | namespace openage {
    type log (line 19) | namespace log {

FILE: libopenage/log/message.h
  function namespace (line 31) | namespace openage {

FILE: libopenage/log/named_logsource.cpp
  type openage::log (line 7) | namespace openage::log {
    function NamedLogSource (line 20) | NamedLogSource &general_source() {

FILE: libopenage/log/named_logsource.h
  function namespace (line 14) | namespace openage {

FILE: libopenage/log/stdout_logsink.cpp
  type openage::log (line 21) | namespace openage::log {
    function enable_ansi_color_codes (line 27) | void enable_ansi_color_codes() {
    function StdOutSink (line 74) | StdOutSink &global_stdoutsink() {

FILE: libopenage/log/stdout_logsink.h
  function namespace (line 7) | namespace openage {

FILE: libopenage/log/test.cpp
  type openage::log::tests (line 14) | namespace openage::log::tests {
    class TestLogSource (line 17) | class TestLogSource : public LogSource {
      method logsource_name (line 19) | std::string logsource_name() override {
    class TestLogSink (line 25) | class TestLogSink : public LogSink {
      method TestLogSink (line 27) | explicit TestLogSink(std::ostream &os) :
      method output_log_message (line 33) | void output_log_message(const message &msg, LogSource * /*source*/) ...
    function demo (line 39) | void demo() {

FILE: libopenage/main.cpp
  type openage (line 11) | namespace openage {
    function run_game (line 18) | int run_game(const main_arguments &args) {

FILE: libopenage/main.h
  function namespace (line 17) | namespace openage {

FILE: libopenage/main/demo/interactive/interactive.cpp
  type openage::main::tests::interactive (line 13) | namespace openage::main::tests::interactive {
    function demo (line 15) | void demo(const util::Path &path) {

FILE: libopenage/main/demo/interactive/interactive.h
  function namespace (line 8) | namespace openage::main::tests::interactive {

FILE: libopenage/main/demo/pong/aicontroller.cpp
  type openage::main::tests::pong (line 6) | namespace openage::main::tests::pong {
    function get_ai_inputs (line 9) | std::vector<PongEvent> get_ai_inputs(const std::shared_ptr<PongPlayer>...

FILE: libopenage/main/demo/pong/aicontroller.h
  function namespace (line 8) | namespace openage::main::tests::pong {

FILE: libopenage/main/demo/pong/gamestate.cpp
  type openage::main::tests::pong (line 11) | namespace openage::main::tests::pong {

FILE: libopenage/main/demo/pong/gamestate.h
  function namespace (line 19) | namespace openage::main::tests::pong {

FILE: libopenage/main/demo/pong/gui.cpp
  type openage::main::tests::pong (line 23) | namespace openage::main::tests::pong {

FILE: libopenage/main/demo/pong/gui.h
  function namespace (line 14) | namespace openage::main::tests::pong {

FILE: libopenage/main/demo/pong/physics.cpp
  type openage::main::tests::pong (line 13) | namespace openage::main::tests::pong {
    class BallReflectWall (line 16) | class BallReflectWall : public event::DependencyEventHandler {
      method BallReflectWall (line 18) | BallReflectWall() :
      method setup_event (line 21) | void setup_event(const std::shared_ptr<event::Event> &evnt,
      method invoke (line 32) | void invoke(event::EventLoop &,
      method predict_invoke_time (line 67) | time::time_t predict_invoke_time(const std::shared_ptr<event::EventE...
    class BallReflectPanel (line 101) | class BallReflectPanel : public event::DependencyEventHandler {
      method BallReflectPanel (line 103) | BallReflectPanel() :
      method setup_event (line 106) | void setup_event(const std::shared_ptr<event::Event> &evnt,
      method invoke (line 116) | void invoke(event::EventLoop &mgr,
      method predict_invoke_time (line 191) | time::time_t predict_invoke_time(const std::shared_ptr<event::EventE...
    class ResetGame (line 234) | class ResetGame : public event::OnceEventHandler {
      method ResetGame (line 236) | ResetGame() :
      method setup_event (line 239) | void setup_event(const std::shared_ptr<event::Event> & /*target*/,
      method invoke (line 242) | void invoke(event::EventLoop & /*mgr*/,
      method predict_invoke_time (line 315) | time::time_t predict_invoke_time(const std::shared_ptr<event::EventE...

FILE: libopenage/main/demo/pong/physics.h
  function namespace (line 11) | namespace openage::event {
  function namespace (line 17) | namespace openage::main::tests::pong {

FILE: libopenage/main/demo/pong/pong.cpp
  type openage::main::tests::pong (line 24) | namespace openage::main::tests::pong {
    type timescale (line 31) | enum class timescale {
    function main (line 38) | void main(const util::Path &path) {

FILE: libopenage/main/demo/pong/pong.h
  function namespace (line 8) | namespace openage::main::tests::pong {

FILE: libopenage/main/demo/presenter/presenter.cpp
  type openage::main::tests::presenter (line 10) | namespace openage::main::tests::presenter {
    function demo (line 12) | void demo(const util::Path &path) {

FILE: libopenage/main/demo/presenter/presenter.h
  function namespace (line 8) | namespace openage::main::tests::presenter {

FILE: libopenage/main/tests.cpp
  type openage::main::tests (line 10) | namespace openage::main::tests {
    function engine_demo (line 13) | void engine_demo(int demo_id, const util::Path &path) {

FILE: libopenage/main/tests.h
  function namespace (line 9) | namespace openage {

FILE: libopenage/options.cpp
  type openage::options (line 6) | namespace openage::options {
    function OptionValue (line 135) | const OptionValue &OptionValue::operator =(const OptionValue &other) {
    function OptionValue (line 199) | OptionValue parse(option_type t, const std::string &s) {
    function OptionValue (line 230) | OptionValue OptionAction::do_action() {
    function OptionValue (line 287) | OptionValue &OptionNode::get_variable_rw(const std::string &name) {
    function OptionValue (line 292) | const OptionValue &OptionNode::get_variable(const std::string &name) c...
    function OptionNode (line 297) | OptionNode *OptionNode::get_child(const std::string &name) const {
    function OptionValue (line 315) | OptionValue OptionNode::do_action(const std::string &aname) {

FILE: libopenage/options.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/pathfinding/cost_field.cpp
  type openage::path (line 12) | namespace openage::path {
    function cost_t (line 25) | cost_t CostField::get_cost(const coord::tile_delta &pos) const {
    function cost_t (line 29) | cost_t CostField::get_cost(size_t x, size_t y) const {
    function cost_t (line 33) | cost_t CostField::get_cost(size_t idx) const {

FILE: libopenage/pathfinding/cost_field.h
  function namespace (line 12) | namespace openage {

FILE: libopenage/pathfinding/definitions.cpp
  type openage::path (line 6) | namespace openage::path {

FILE: libopenage/pathfinding/definitions.h
  function namespace (line 10) | namespace openage::path {

FILE: libopenage/pathfinding/demo/demo_0.cpp
  type openage::path::tests (line 27) | namespace openage::path::tests {
    function path_demo_0 (line 29) | void path_demo_0(const util::Path &path) {

FILE: libopenage/pathfinding/demo/demo_0.h
  function namespace (line 10) | namespace openage {

FILE: libopenage/pathfinding/demo/demo_1.cpp
  type openage::path::tests (line 25) | namespace openage::path::tests {
    function path_demo_1 (line 27) | void path_demo_1(const util::Path &path) {

FILE: libopenage/pathfinding/demo/demo_1.h
  function namespace (line 11) | namespace openage {

FILE: libopenage/pathfinding/demo/tests.cpp
  type openage::path::tests (line 11) | namespace openage::path::tests {
    function path_demo (line 13) | void path_demo(int demo_id, const util::Path &path) {

FILE: libopenage/pathfinding/demo/tests.h
  function namespace (line 9) | namespace openage {

FILE: libopenage/pathfinding/field_cache.cpp
  type openage::path (line 5) | namespace openage::path {
    function field_cache_t (line 28) | field_cache_t FieldCache::get(const cache_key_t cache_key) const {

FILE: libopenage/pathfinding/field_cache.h
  function namespace (line 12) | namespace openage {

FILE: libopenage/pathfinding/flow_field.cpp
  type openage::path (line 15) | namespace openage::path {
    function flow_t (line 33) | flow_t FlowField::get_cell(const coord::tile_delta &pos) const {
    function flow_t (line 37) | flow_t FlowField::get_cell(size_t x, size_t y) const {
    function flow_t (line 41) | flow_t FlowField::get_cell(size_t idx) const {
    function flow_dir_t (line 45) | flow_dir_t FlowField::get_dir(const coord::tile_delta &pos) const {
    function flow_dir_t (line 49) | flow_dir_t FlowField::get_dir(size_t x, size_t y) const {
    function flow_dir_t (line 53) | flow_dir_t FlowField::get_dir(size_t idx) const {

FILE: libopenage/pathfinding/flow_field.h
  function namespace (line 14) | namespace openage {

FILE: libopenage/pathfinding/grid.cpp
  type openage::path (line 12) | namespace openage::path {
    function grid_id_t (line 43) | grid_id_t Grid::get_id() const {
    function nodemap_t (line 101) | const nodemap_t &Grid::get_portal_map() {

FILE: libopenage/pathfinding/grid.h
  function namespace (line 15) | namespace openage::path {

FILE: libopenage/pathfinding/integration_field.cpp
  type openage::path (line 16) | namespace openage::path {
    function integrated_t (line 28) | const integrated_t &IntegrationField::get_cell(const coord::tile_delta...
    function integrated_t (line 32) | const integrated_t &IntegrationField::get_cell(size_t x, size_t y) con...
    function integrated_t (line 36) | const integrated_t &IntegrationField::get_cell(size_t idx) const {

FILE: libopenage/pathfinding/integration_field.h
  function namespace (line 14) | namespace openage {

FILE: libopenage/pathfinding/integrator.cpp
  type openage::path (line 15) | namespace openage::path {

FILE: libopenage/pathfinding/integrator.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/pathfinding/legacy/a_star.cpp
  type openage (line 24) | namespace openage {
    type path::legacy (line 25) | namespace path::legacy {
      function Path (line 28) | Path to_point(coord::phys3 start,
      function Path (line 40) | Path find_nearest(coord::phys3 start,
      function Path (line 48) | Path a_star(coord::phys3 start,

FILE: libopenage/pathfinding/legacy/a_star.h
  function namespace (line 10) | namespace openage {

FILE: libopenage/pathfinding/legacy/heuristics.cpp
  type openage (line 9) | namespace openage {
    type path::legacy (line 10) | namespace path::legacy {
      function cost_old_t (line 12) | cost_old_t manhattan_cost(const coord::phys3 &start, const coord::ph...
      function cost_old_t (line 18) | cost_old_t chebyshev_cost(const coord::phys3 &start, const coord::ph...
      function cost_old_t (line 24) | cost_old_t euclidean_cost(const coord::phys3 &start, const coord::ph...
      function cost_old_t (line 28) | cost_old_t euclidean_squared_cost(const coord::phys3 &start, const c...

FILE: libopenage/pathfinding/legacy/heuristics.h
  function namespace (line 7) | namespace openage {

FILE: libopenage/pathfinding/legacy/path.cpp
  type openage::path::legacy (line 7) | namespace openage::path::legacy {
    function cost_old_t (line 53) | cost_old_t Node::cost_to(const Node &other) const {
    function Path (line 60) | Path Node::generate_backtrace() {
    function passable_line (line 93) | bool passable_line(node_pt start, node_pt end, std::function<bool(cons...

FILE: libopenage/pathfinding/legacy/path.h
  function namespace (line 17) | namespace openage {

FILE: libopenage/pathfinding/legacy/path_utils.h
  function namespace (line 5) | namespace openage {

FILE: libopenage/pathfinding/legacy/tests.cpp
  type openage (line 9) | namespace openage {
    type path (line 10) | namespace path {
      type tests (line 11) | namespace tests {
        function node_0 (line 17) | void node_0() {
        function node_cost_to_0 (line 93) | void node_cost_to_0() {
        function node_cost_to_1 (line 132) | void node_cost_to_1() {
        function node_generate_backtrace_0 (line 169) | void node_generate_backtrace_0() {
        function node_get_neighbors_0 (line 191) | void node_get_neighbors_0() {
        function always_passable (line 259) | bool always_passable(const coord::phys3 &) {
        function not_passable (line 266) | bool not_passable(const coord::phys3 &) {
        function sometimes_passable (line 274) | bool sometimes_passable(const coord::phys3 &pos) {
        function node_passable_line_0 (line 287) | void node_passable_line_0() {
        function path_node (line 306) | void path_node() {

FILE: libopenage/pathfinding/path.cpp
  type openage::path (line 6) | namespace openage::path {

FILE: libopenage/pathfinding/path.h
  function namespace (line 12) | namespace openage::path {

FILE: libopenage/pathfinding/pathfinder.cpp
  type openage::path (line 17) | namespace openage::path {
    function Path (line 24) | const Path Pathfinder::get_path(const PathRequest &request) {

FILE: libopenage/pathfinding/pathfinder.h
  function namespace (line 16) | namespace openage::path {

FILE: libopenage/pathfinding/portal.cpp
  type openage::path (line 8) | namespace openage::path {
    function portal_id_t (line 26) | portal_id_t Portal::get_id() const {
    function sector_id_t (line 59) | sector_id_t Portal::get_exit_sector(sector_id_t entry_sector) const {
    function PortalDirection (line 136) | PortalDirection Portal::get_direction() const {

FILE: libopenage/pathfinding/portal.h
  function namespace (line 13) | namespace openage::path {

FILE: libopenage/pathfinding/sector.cpp
  type openage::path (line 15) | namespace openage::path {
    function sector_id_t (line 29) | const sector_id_t &Sector::get_id() const {

FILE: libopenage/pathfinding/sector.h
  function namespace (line 14) | namespace openage::path {

FILE: libopenage/pathfinding/tests.cpp
  type openage (line 16) | namespace openage {
    type path (line 17) | namespace path {
      type tests (line 18) | namespace tests {
        function flow_field (line 20) | void flow_field() {

FILE: libopenage/pathfinding/types.cpp
  type openage::path (line 6) | namespace openage::path {

FILE: libopenage/pathfinding/types.h
  type class (line 16) | enum class
  type integrated_t (line 49) | struct integrated_t {
  function flow_dir_t (line 77) | enum class flow_dir_t : uint8_t {

FILE: libopenage/presenter/presenter.cpp
  type openage::presenter (line 39) | namespace openage::presenter {

FILE: libopenage/presenter/presenter.h
  function namespace (line 12) | namespace qtgui {
  function namespace (line 16) | namespace openage {

FILE: libopenage/pyinterface/defs.cpp
  type openage (line 6) | namespace openage {
    type pyinterface (line 7) | namespace pyinterface {

FILE: libopenage/pyinterface/defs.h
  type PyObject (line 10) | typedef struct _object PyObject;

FILE: libopenage/pyinterface/exctranslate.cpp
  type openage (line 19) | namespace openage {
    type pyinterface (line 20) | namespace pyinterface {
      function set_exc_translation_funcs (line 31) | void set_exc_translation_funcs(
      function translate_exc_cpp_to_py (line 47) | void translate_exc_cpp_to_py() {
      function translate_exc_py_to_cpp (line 93) | void translate_exc_py_to_cpp() {
      function init_exc_message (line 120) | void init_exc_message(log::message *msg, const std::string &filename...

FILE: libopenage/pyinterface/exctranslate.h
  function namespace (line 24) | namespace openage {

FILE: libopenage/pyinterface/exctranslate_tests.cpp
  type openage::pyinterface::tests (line 12) | namespace openage::pyinterface::tests {
    function throw_foo (line 16) | void throw_foo() {
    function err_cpp_to_py_helper (line 27) | void err_cpp_to_py_helper() {
    function err_py_to_cpp (line 40) | void err_py_to_cpp() {
    function err_py_to_cpp_demo (line 106) | void err_py_to_cpp_demo() {
    function bounce_call (line 120) | void bounce_call(const Func<void> &func, int times) {

FILE: libopenage/pyinterface/exctranslate_tests.h
  function namespace (line 8) | namespace openage {

FILE: libopenage/pyinterface/functional.cpp
  type openage (line 5) | namespace openage {
    type pyinterface (line 6) | namespace pyinterface {

FILE: libopenage/pyinterface/functional.h
  function namespace (line 15) | namespace openage {
  function bind0 (line 201) | inline void bind0(ReturnType (*f)(ArgTypes...)) {
  function bind_noexcept0 (line 206) | inline void bind_noexcept0(ReturnType (*f)(ArgTypes...)) {

FILE: libopenage/pyinterface/pyexception.cpp
  type openage (line 7) | namespace openage {
    type pyinterface (line 8) | namespace pyinterface {

FILE: libopenage/pyinterface/pyexception.h
  function namespace (line 22) | namespace openage {

FILE: libopenage/pyinterface/pyobject.cpp
  type openage (line 9) | namespace openage {
    type pyinterface (line 10) | namespace pyinterface {
      function PyObjectRef (line 43) | PyObjectRef &PyObjectRef::operator =(const PyObjectRef &other) {
      function PyObjectRef (line 55) | PyObjectRef &PyObjectRef::operator =(PyObjectRef &&other) {
      function PyObjectRef (line 147) | PyObjectRef PyObjectRef::call_impl(std::vector<PyObjectRef> &args) c...
      function PyObjectRef (line 166) | PyObjectRef PyObjectRef::getattr(const std::string &name) const {
      function PyObjectRef (line 208) | PyObjectRef PyObjectRef::eval(const std::string &expression) const {
      function PyObjectRef (line 220) | PyObjectRef PyObjectRef::get(const PyObjectRef &key) const {
      function PyObjectRef (line 227) | PyObjectRef PyObjectRef::get(const std::string &key) const {
      function PyObjectRef (line 233) | PyObjectRef PyObjectRef::get(int key) const {
      function PyObjectRef (line 244) | PyObjectRef PyObjectRef::type() const {
    type py (line 313) | namespace py {
      function Obj (line 317) | Obj builtin(const std::string &name) {
      function Obj (line 324) | Obj import(const std::string &name) {
      function Obj (line 331) | Obj str(const std::string &value) {
      function Obj (line 338) | Obj bytes(const std::string &value) {
      function Obj (line 345) | Obj integer(int value) {
      function Obj (line 352) | Obj dict() {
      function Obj (line 359) | Obj list() {

FILE: libopenage/pyinterface/pyobject.h
  function namespace (line 22) | namespace openage {

FILE: libopenage/pyinterface/pyobject_tests.cpp
  type openage (line 12) | namespace openage {
    type pyinterface (line 13) | namespace pyinterface {
      type tests (line 14) | namespace tests {
        function pyobject (line 16) | void pyobject() {
        function pyobject_demo (line 133) | void pyobject_demo() {

FILE: libopenage/pyinterface/pyobject_tests.h
  function namespace (line 5) | namespace openage {

FILE: libopenage/pyinterface/setup.cpp
  type openage::pyinterface (line 13) | namespace openage::pyinterface {
    type state (line 20) | struct state {
      method state (line 34) | static state &get() {
    function add_py_if_component (line 44) | void add_py_if_component(void *thisptr, std::function<bool ()> checker) {
    function destroy_py_if_component (line 63) | void destroy_py_if_component(void *thisptr) {
    function check (line 73) | void check() {

FILE: libopenage/pyinterface/setup.h
  function namespace (line 18) | namespace openage {

FILE: libopenage/renderer/camera/boundaries.cpp
  type openage::renderer::camera (line 6) | namespace openage::renderer::camera {

FILE: libopenage/renderer/camera/boundaries.h
  function namespace (line 5) | namespace openage::renderer::camera {

FILE: libopenage/renderer/camera/camera.cpp
  type openage::renderer::camera (line 16) | namespace openage::renderer::camera {
    function Frustum2d (line 238) | const Frustum2d Camera::get_frustum_2d() {
    function Frustum3d (line 245) | const Frustum3d Camera::get_frustum_3d() const {

FILE: libopenage/renderer/camera/camera.h
  function namespace (line 23) | namespace openage::renderer {

FILE: libopenage/renderer/camera/definitions.cpp
  type openage::renderer::camera (line 5) | namespace openage::renderer::camera {

FILE: libopenage/renderer/camera/definitions.h
  function CameraBoundaries (line 63) | static constexpr CameraBoundaries DEFAULT_CAM_BOUNDARIES{

FILE: libopenage/renderer/camera/frustum_2d.cpp
  type openage::renderer::camera (line 6) | namespace openage::renderer::camera {

FILE: libopenage/renderer/camera/frustum_2d.h
  function namespace (line 9) | namespace openage::renderer::camera {

FILE: libopenage/renderer/camera/frustum_3d.cpp
  type openage::renderer::camera (line 6) | namespace openage::renderer::camera {

FILE: libopenage/renderer/camera/frustum_3d.h
  function namespace (line 10) | namespace openage::renderer::camera {

FILE: libopenage/renderer/color.cpp
  type openage (line 5) | namespace openage {
    type renderer (line 6) | namespace renderer {

FILE: libopenage/renderer/color.h
  function namespace (line 7) | namespace openage {

FILE: libopenage/renderer/definitions.cpp
  type openage::renderer (line 5) | namespace openage::renderer {

FILE: libopenage/renderer/definitions.h
  function namespace (line 15) | namespace openage::renderer {

FILE: libopenage/renderer/demo/demo_0.cpp
  type openage::renderer::tests (line 15) | namespace openage::renderer::tests {
    function renderer_demo_0 (line 17) | void renderer_demo_0(const util::Path &path) {

FILE: libopenage/renderer/demo/demo_0.h
  function namespace (line 7) | namespace openage::renderer::tests {

FILE: libopenage/renderer/demo/demo_1.cpp
  type openage::renderer::tests (line 21) | namespace openage::renderer::tests {
    function renderer_demo_1 (line 23) | void renderer_demo_1(const util::Path &path) {

FILE: libopenage/renderer/demo/demo_1.h
  function namespace (line 7) | namespace openage::renderer::tests {

FILE: libopenage/renderer/demo/demo_2.cpp
  type openage::renderer::tests (line 24) | namespace openage::renderer::tests {
    function renderer_demo_2 (line 26) | void renderer_demo_2(const util::Path &path) {

FILE: libopenage/renderer/demo/demo_2.h
  function namespace (line 7) | namespace openage::renderer::tests {

FILE: libopenage/renderer/demo/demo_3.cpp
  type openage::renderer::tests (line 28) | namespace openage::renderer::tests {
    function renderer_demo_3 (line 30) | void renderer_demo_3(const util::Path &path) {

FILE: libopenage/renderer/demo/demo_3.h
  function namespace (line 7) | namespace openage::renderer::tests {

FILE: libopenage/renderer/demo/demo_4.cpp
  type openage::renderer::tests (line 23) | namespace openage::renderer::tests {
    function renderer_demo_4 (line 24) | void renderer_demo_4(const util::Path &path) {

FILE: libopenage/renderer/demo/demo_4.h
  function namespace (line 7) | namespace openage::renderer::tests {

FILE: libopenage/renderer/demo/demo_5.cpp
  type openage::renderer::tests (line 23) | namespace openage::renderer::tests {
    function renderer_demo_5 (line 25) | void renderer_demo_5(const util::Path &path) {

FILE: libopenage/renderer/demo/demo_5.h
  function namespace (line 7) | namespace openage::renderer::tests {

FILE: libopenage/renderer/demo/demo_6.cpp
  type openage::renderer::tests (line 32) | namespace openage::renderer::tests {
    function renderer_demo_6 (line 34) | void renderer_demo_6(const util::Path &path) {

FILE: libopenage/renderer/demo/demo_6.h
  function namespace (line 14) | namespace openage::renderer {

FILE: libopenage/renderer/demo/demo_7.cpp
  type openage::renderer::tests (line 18) | namespace openage::renderer::tests {
    function renderer_demo_7 (line 20) | void renderer_demo_7(const util::Path &path) {

FILE: libopenage/renderer/demo/demo_7.h
  function namespace (line 7) | namespace openage::renderer::tests {

FILE: libopenage/renderer/demo/stresstest_0.cpp
  type openage::renderer::tests (line 28) | namespace openage::renderer::tests {
    function renderer_stresstest_0 (line 30) | void renderer_stresstest_0(const util::Path &path) {

FILE: libopenage/renderer/demo/stresstest_0.h
  function namespace (line 8) | namespace openage::renderer::tests {

FILE: libopenage/renderer/demo/stresstest_1.cpp
  type openage::renderer::tests (line 26) | namespace openage::renderer::tests {
    function renderer_stresstest_1 (line 27) | void renderer_stresstest_1(const util::Path &path) {

FILE: libopenage/renderer/demo/stresstest_1.h
  function namespace (line 7) | namespace openage::renderer::tests {

FILE: libopenage/renderer/demo/tests.cpp
  type openage::renderer::tests (line 19) | namespace openage::renderer::tests {
    function renderer_demo (line 21) | void renderer_demo(int demo_id, const util::Path &path) {
    function OAAPI (line 61) | OAAPI void renderer_stresstest(int demo_id, const util::Path &path) {

FILE: libopenage/renderer/demo/tests.h
  function namespace (line 9) | namespace openage {

FILE: libopenage/renderer/demo/util.cpp
  type openage::renderer::tests (line 8) | namespace openage::renderer::tests {
    function check_uniform_completeness (line 10) | bool check_uniform_completeness(const std::vector<Renderable> &rendera...

FILE: libopenage/renderer/demo/util.h
  function namespace (line 9) | namespace openage::renderer::tests {

FILE: libopenage/renderer/font/font.cpp
  type openage::renderer (line 15) | namespace openage::renderer {
    function font_description (line 37) | font_description &font_description::operator=(const font_description &...
    function hb_direction_t (line 71) | static hb_direction_t get_hb_font_direction(const font_description &de...
    function hb_language_t (line 86) | static hb_language_t get_hb_font_language(const font_description &desc...
    function hb_script_t (line 90) | static hb_script_t get_hb_font_script(const font_description &descript...

FILE: libopenage/renderer/font/font.h
  type hb_font_t (line 14) | struct hb_font_t
  function class (line 26) | class Glyph {
  type class (line 40) | enum class
  type font_description (line 52) | struct font_description {
  function get_ascender (line 119) | float get_ascender() const;

FILE: libopenage/renderer/font/font_manager.cpp
  type openage::renderer (line 11) | namespace openage::renderer {
    function FT_Library (line 56) | FT_Library FontManager::get_ft_library() {
    function Font (line 60) | Font *FontManager::get_font(const char *family, const char *style, uns...
    function Font (line 65) | Font *FontManager::get_font(const char *font_file, unsigned int size) {

FILE: libopenage/renderer/font/font_manager.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/renderer/font/glyph_atlas.cpp
  type openage::renderer (line 15) | namespace openage::renderer {

FILE: libopenage/renderer/font/glyph_atlas.h
  function namespace (line 11) | namespace openage {

FILE: libopenage/renderer/font/tests.cpp
  type openage (line 8) | namespace openage {
    type renderer (line 9) | namespace renderer {
      type tests (line 10) | namespace tests {
        function font_manager_test_get_font (line 12) | void font_manager_test_get_font() {
        function font_manager (line 25) | void font_manager() {
        function font_test_font_description (line 29) | void font_test_font_description() {
        function font (line 59) | void font() {

FILE: libopenage/renderer/geometry.cpp
  type openage (line 6) | namespace openage {
    type renderer (line 7) | namespace renderer {
      function geometry_t (line 12) | geometry_t Geometry::get_type() const {

FILE: libopenage/renderer/geometry.h
  function namespace (line 10) | namespace openage {

FILE: libopenage/renderer/gui/gui.cpp
  type openage::renderer::gui (line 20) | namespace openage::renderer::gui {

FILE: libopenage/renderer/gui/gui.h
  function namespace (line 11) | namespace qtgui {
  function namespace (line 18) | namespace openage {

FILE: libopenage/renderer/gui/guisys/link/gui_item.cpp
  type qtgui (line 6) | namespace qtgui {
    function QString (line 9) | QString name_tidier(const char *name) {

FILE: libopenage/renderer/gui/guisys/link/gui_item.h
  function namespace (line 22) | namespace qtgui {
  function do_adopt_core (line 251) | void do_adopt_core(PersistentCoreHolderBase *holder, const QString &tag) {
  function class (line 315) | class NullClass {
  function virtual (line 357) | virtual ~Inherits() {

FILE: libopenage/renderer/gui/guisys/link/gui_item_link.h
  function namespace (line 11) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/link/gui_item_list_model.h
  function namespace (line 12) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/link/gui_list_model.cpp
  type qtgui (line 8) | namespace qtgui {
    function QVariant (line 52) | QVariant GuiListModel::data(const QModelIndex &index, int role) const {

FILE: libopenage/renderer/gui/guisys/link/gui_list_model.h
  function namespace (line 13) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/link/gui_property_map_impl.cpp
  type qtgui (line 11) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/link/gui_property_map_impl.h
  function namespace (line 8) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/link/gui_singleton_item.cpp
  type qtgui (line 6) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/link/gui_singleton_item.h
  function namespace (line 10) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/link/qtgui_checked_static_cast.h
  function namespace (line 8) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/private/gui_application_impl.cpp
  type qtgui (line 12) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/private/gui_application_impl.h
  function namespace (line 10) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/private/gui_ctx_setup.cpp
  type qtgui (line 17) | namespace qtgui {
    function QQuickGraphicsDevice (line 71) | QQuickGraphicsDevice GlGuiRenderingContext::get_device() {
    function QQuickGraphicsDevice (line 97) | QQuickGraphicsDevice GuiUniqueRenderingContext::get_device() {
    function QQuickGraphicsDevice (line 138) | QQuickGraphicsDevice GuiSeparateRenderingContext::get_device() {

FILE: libopenage/renderer/gui/guisys/private/gui_ctx_setup.h
  function class (line 21) | class CtxExtractionException : public std::runtime_error {
  function std (line 37) | const std::shared_ptr<QOpenGLContext> &get_ctx() const;

FILE: libopenage/renderer/gui/guisys/private/gui_engine_impl.cpp
  type qtgui (line 15) | namespace qtgui {
    function GuiQmlEngineImpl (line 41) | GuiQmlEngineImpl *GuiQmlEngineImpl::impl(GuiQmlEngine *engine) {

FILE: libopenage/renderer/gui/guisys/private/gui_engine_impl.h
  function namespace (line 13) | QT_FORWARD_DECLARE_CLASS(QQmlEngine)

FILE: libopenage/renderer/gui/guisys/private/gui_input_impl.cpp
  type qtgui (line 11) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/private/gui_input_impl.h
  function namespace (line 12) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/private/gui_renderer_impl.cpp
  type qtgui (line 23) | namespace qtgui {
    function GuiRendererImpl (line 115) | GuiRendererImpl *GuiRendererImpl::impl(GuiRenderer *renderer) {

FILE: libopenage/renderer/gui/guisys/private/gui_renderer_impl.h
  function namespace (line 26) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/private/gui_rendering_setup_routines.cpp
  type qtgui (line 11) | namespace qtgui {
    function GuiRenderingCtxActivator (line 59) | GuiRenderingCtxActivator &GuiRenderingCtxActivator::operator=(GuiRende...

FILE: libopenage/renderer/gui/guisys/private/gui_rendering_setup_routines.h
  function namespace (line 15) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/private/gui_subtree_impl.cpp
  type qtgui (line 23) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/private/gui_subtree_impl.h
  function namespace (line 12) | QT_FORWARD_DECLARE_CLASS(QQuickItem)

FILE: libopenage/renderer/gui/guisys/private/livereload/deferred_initial_constant_property_values.cpp
  type qtgui (line 5) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/private/livereload/deferred_initial_constant_property_values.h
  function namespace (line 8) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/private/livereload/gui_live_reloader.cpp
  type qtgui (line 11) | namespace qtgui {
    function GuiItemBase (line 27) | GuiItemBase *GuiLiveReloaderAttachedProperty::get_attachee() const {
    function QString (line 34) | QString GuiLiveReloaderAttachedProperty::get_tag() const {
    function QString (line 46) | QString GuiLiveReloaderAttachedProperty::get_tag_for_init() const {
    function GuiLiveReloaderAttachedProperty (line 50) | GuiLiveReloaderAttachedProperty *GuiLiveReloaderAttachedPropertyProvid...

FILE: libopenage/renderer/gui/guisys/private/livereload/gui_live_reloader.h
  function namespace (line 17) | namespace std {
  function class (line 34) | class GuiLiveReloaderAttachedProperty : public QObject {

FILE: libopenage/renderer/gui/guisys/private/livereload/recursive_directory_watcher.cpp
  type qtgui (line 10) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/private/livereload/recursive_directory_watcher.h
  function namespace (line 10) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/private/livereload/recursive_directory_watcher_worker.cpp
  type qtgui (line 10) | namespace qtgui {
    function QStringList (line 32) | QStringList collect_entries_to_watch(const QStringList &root_dirs_path...

FILE: libopenage/renderer/gui/guisys/private/livereload/recursive_directory_watcher_worker.h
  function namespace (line 11) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/private/opengl_debug_logger.cpp
  type qtgui (line 17) | namespace qtgui {
    function gl_debug_parameters (line 19) | gl_debug_parameters get_current_opengl_debug_parameters(QOpenGLContext...
    function apply_opengl_debug_parameters (line 31) | void apply_opengl_debug_parameters(gl_debug_parameters params, QOpenGL...

FILE: libopenage/renderer/gui/guisys/private/opengl_debug_logger.h
  function namespace (line 7) | QT_FORWARD_DECLARE_CLASS(QOpenGLContext)

FILE: libopenage/renderer/gui/guisys/public/gui_application.cpp
  type qtgui (line 9) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/public/gui_application.h
  function namespace (line 7) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/public/gui_engine.cpp
  type qtgui (line 7) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/public/gui_engine.h
  function namespace (line 12) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/public/gui_input.cpp
  type qtgui (line 7) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/public/gui_input.h
  function namespace (line 11) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/public/gui_renderer.cpp
  type qtgui (line 9) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/public/gui_renderer.h
  function namespace (line 16) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/public/gui_subtree.cpp
  type qtgui (line 7) | namespace qtgui {

FILE: libopenage/renderer/gui/guisys/public/gui_subtree.h
  function namespace (line 9) | namespace qtgui {

FILE: libopenage/renderer/gui/integration/private/gui_filled_texture_handles.cpp
  type openage::renderer::gui (line 10) | namespace openage::renderer::gui {

FILE: libopenage/renderer/gui/integration/private/gui_filled_texture_handles.h
  function namespace (line 13) | namespace openage::renderer::gui {

FILE: libopenage/renderer/gui/integration/private/gui_log.cpp
  type openage::renderer::gui (line 11) | namespace openage::renderer::gui {
    function gui_log (line 13) | void gui_log(QtMsgType type, const QMessageLogContext &context, const ...

FILE: libopenage/renderer/gui/integration/private/gui_log.h
  function namespace (line 7) | namespace openage::renderer::gui {

FILE: libopenage/renderer/gui/integration/private/gui_make_standalone_subtexture.cpp
  type openage::renderer::gui (line 8) | namespace openage::renderer::gui {
    function make_standalone_subtexture (line 10) | std::unique_ptr<QSGTexture> make_standalone_subtexture(GLuint id, cons...

FILE: libopenage/renderer/gui/integration/private/gui_make_standalone_subtexture.h
  function namespace (line 11) | namespace openage::renderer::gui {

FILE: libopenage/renderer/gui/integration/private/gui_standalone_subtexture.cpp
  type openage::renderer::gui (line 5) | namespace openage::renderer::gui {
    function qint64 (line 20) | qint64 GuiStandaloneSubtexture::comparisonKey() const {
    function QSize (line 41) | QSize GuiStandaloneSubtexture::textureSize() const {

FILE: libopenage/renderer/gui/integration/private/gui_standalone_subtexture.h
  function namespace (line 8) | namespace openage::renderer::gui {

FILE: libopenage/renderer/gui/integration/private/gui_texture.cpp
  type openage::renderer::gui (line 11) | namespace openage::renderer::gui {
    function qint64 (line 24) | qint64 GuiTexture::comparisonKey() const {
    function QSGTexture (line 42) | QSGTexture *GuiTexture::removedFromAtlas(QRhiResourceUpdateBatch * /* ...
    function QRectF (line 50) | QRectF GuiTexture::normalizedTextureSubRect() const {
    function QSize (line 58) | QSize GuiTexture::textureSize() const {

FILE: libopenage/renderer/gui/integration/private/gui_texture.h
  function namespace (line 11) | namespace openage::renderer::gui {

FILE: libopenage/renderer/gui/integration/private/gui_texture_handle.cpp
  type openage::renderer::gui (line 8) | namespace openage::renderer::gui {
    function isAtlasTexture (line 20) | bool isAtlasTexture(const TextureHandle &texture_handle) {
    function QSize (line 24) | QSize textureSize(const SizedTextureHandle &texture_handle) {
    function QSize (line 28) | QSize native_size(const TextureHandle & /* texture_handle */) {
    function QSize (line 32) | QSize aspect_fit_size(const TextureHandle &texture_handle, const QSize...

FILE: libopenage/renderer/gui/integration/private/gui_texture_handle.h
  function namespace (line 7) | namespace openage::renderer::gui {

FILE: libopenage/renderer/gui/integration/public/gui_application_with_logger.cpp
  type openage::renderer::gui (line 8) | namespace openage::renderer::gui {
    function create (line 11) | std::shared_ptr<qtgui::GuiApplicationImpl> create() {

FILE: libopenage/renderer/gui/integration/public/gui_application_with_logger.h
  function namespace (line 7) | namespace openage::renderer::gui {

FILE: libopenage/renderer/opengl/buffer.cpp
  type openage (line 8) | namespace openage {
    type renderer (line 9) | namespace renderer {
      type opengl (line 10) | namespace opengl {

FILE: libopenage/renderer/opengl/buffer.h
  function namespace (line 8) | namespace openage {

FILE: libopenage/renderer/opengl/context.cpp
  type openage::renderer::opengl (line 18) | namespace openage::renderer::opengl {
    function gl_context_spec (line 24) | gl_context_spec GlContext::find_spec() {
    function GlContext (line 149) | GlContext &GlContext::operator=(GlContext &&other) {
    function GLuint (line 161) | GLuint GlContext::get_default_framebuffer_id() {
    function gl_context_spec (line 165) | gl_context_spec GlContext::get_specs() const {

FILE: libopenage/renderer/opengl/context.h
  function QT_FORWARD_DECLARE_CLASS (line 9) | QT_FORWARD_DECLARE_CLASS(QWindow)

FILE: libopenage/renderer/opengl/debug.cpp
  type openage::renderer::opengl (line 11) | namespace openage::renderer::opengl {

FILE: libopenage/renderer/opengl/debug.h
  function class (line 12) | class GlDebugLogHandler : public QObject {

FILE: libopenage/renderer/opengl/error.cpp
  type openage::renderer::opengl (line 9) | namespace openage::renderer::opengl {
    function gl_check_error (line 11) | void gl_check_error() {

FILE: libopenage/renderer/opengl/error.h
  function namespace (line 5) | namespace openage::renderer::opengl {

FILE: libopenage/renderer/opengl/framebuffer.cpp
  type openage::renderer::opengl (line 11) | namespace openage::renderer::opengl {
    function gl_framebuffer_t (line 61) | gl_framebuffer_t GlFramebuffer::get_type() const {

FILE: libopenage/renderer/opengl/framebuffer.h
  function namespace (line 10) | namespace openage::renderer::opengl {

FILE: libopenage/renderer/opengl/geometry.cpp
  type openage (line 13) | namespace openage {
    type renderer (line 14) | namespace renderer {
      type opengl (line 15) | namespace opengl {

FILE: libopenage/renderer/opengl/geometry.h
  function namespace (line 14) | namespace openage {

FILE: libopenage/renderer/opengl/lookup.h
  function namespace (line 15) | namespace openage {

FILE: libopenage/renderer/opengl/render_pass.cpp
  type openage::renderer::opengl (line 8) | namespace openage::renderer::opengl {

FILE: libopenage/renderer/opengl/render_pass.h
  function namespace (line 9) | namespace openage::renderer::opengl {

FILE: libopenage/renderer/opengl/render_target.cpp
  type openage::renderer::opengl (line 11) | namespace openage::renderer::opengl {
    function gl_render_target_t (line 44) | gl_render_target_t GlRenderTarget::get_type() const {

FILE: libopenage/renderer/opengl/render_target.h
  function namespace (line 12) | namespace openage {

FILE: libopenage/renderer/opengl/renderer.cpp
  type openage::renderer::opengl (line 23) | namespace openage::renderer::opengl {

FILE: libopenage/renderer/opengl/renderer.h
  function namespace (line 11) | namespace openage {

FILE: libopenage/renderer/opengl/shader.cpp
  type openage (line 8) | namespace openage {
    type renderer (line 9) | namespace renderer {
      type opengl (line 10) | namespace opengl {
        function GLenum (line 55) | GLenum GlShader::get_type() const {

FILE: libopenage/renderer/opengl/shader.h
  function namespace (line 9) | namespace openage {

FILE: libopenage/renderer/opengl/shader_data.cpp
  type openage::renderer::opengl (line 6) | namespace openage::renderer::opengl {

FILE: libopenage/renderer/opengl/shader_data.h
  function namespace (line 12) | namespace openage::renderer::opengl {

FILE: libopenage/renderer/opengl/shader_program.cpp
  type openage::renderer::opengl (line 24) | namespace openage::renderer::opengl {
    function check_program_status (line 26) | static void check_program_status(GLuint program, GLenum what_to_check) {
    function GlUniformBlock (line 440) | const GlUniformBlock &GlShaderProgram::get_uniform_block(const char *n...
    function uniform_id_t (line 460) | uniform_id_t GlShaderProgram::get_uniform_id(const char *name) {

FILE: libopenage/renderer/opengl/shader_program.h
  function namespace (line 15) | namespace openage {

FILE: libopenage/renderer/opengl/simple_object.cpp
  type openage (line 8) | namespace openage {
    type renderer (line 9) | namespace renderer {
      type opengl (line 10) | namespace opengl {
        function GlSimpleObject (line 24) | GlSimpleObject &GlSimpleObject::operator=(GlSimpleObject &&other) {
        function GLuint (line 43) | GLuint GlSimpleObject::get_handle() const {

FILE: libopenage/renderer/opengl/simple_object.h
  function namespace (line 12) | namespace openage {

FILE: libopenage/renderer/opengl/texture.cpp
  type openage (line 18) | namespace openage {
    type renderer (line 19) | namespace renderer {
      type opengl (line 20) | namespace opengl {

FILE: libopenage/renderer/opengl/texture.h
  function namespace (line 10) | namespace openage {

FILE: libopenage/renderer/opengl/texture_array.cpp
  type openage (line 18) | namespace openage {
    type renderer (line 19) | namespace renderer {
      type opengl (line 20) | namespace opengl {

FILE: libopenage/renderer/opengl/texture_array.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/renderer/opengl/uniform_buffer.cpp
  type openage::renderer::opengl (line 15) | namespace openage::renderer::opengl {
    function GLuint (line 49) | GLuint GlUniformBuffer::get_binding_point() const {

FILE: libopenage/renderer/opengl/uniform_buffer.h
  function namespace (line 11) | namespace openage::renderer {

FILE: libopenage/renderer/opengl/uniform_input.cpp
  type openage::renderer::opengl (line 11) | namespace openage::renderer::opengl {

FILE: libopenage/renderer/opengl/uniform_input.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/renderer/opengl/util.cpp
  type openage::renderer::opengl (line 5) | namespace openage::renderer::opengl {

FILE: libopenage/renderer/opengl/util.h
  function namespace (line 12) | namespace openage::renderer::opengl {

FILE: libopenage/renderer/opengl/vertex_array.cpp
  type openage (line 13) | namespace openage {
    type renderer (line 14) | namespace renderer {
      type opengl (line 15) | namespace opengl {

FILE: libopenage/renderer/opengl/vertex_array.h
  function namespace (line 10) | namespace openage {

FILE: libopenage/renderer/opengl/window.cpp
  type openage::renderer::opengl (line 18) | namespace openage::renderer::opengl {

FILE: libopenage/renderer/opengl/window.h
  function QT_FORWARD_DECLARE_CLASS (line 10) | QT_FORWARD_DECLARE_CLASS(QWindow)

FILE: libopenage/renderer/render_factory.cpp
  type openage::renderer (line 11) | namespace openage::renderer {

FILE: libopenage/renderer/render_factory.h
  function namespace (line 11) | namespace openage::renderer {

FILE: libopenage/renderer/render_pass.cpp
  type openage::renderer (line 8) | namespace openage::renderer {

FILE: libopenage/renderer/render_pass.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/renderer/render_target.cpp
  type openage::renderer (line 6) | namespace openage::renderer {

FILE: libopenage/renderer/render_target.h
  function namespace (line 9) | namespace openage {

FILE: libopenage/renderer/renderable.cpp
  type openage::renderer (line 6) | namespace openage::renderer {

FILE: libopenage/renderer/renderable.h
  function namespace (line 8) | namespace openage {

FILE: libopenage/renderer/renderer.cpp
  type openage::renderer (line 5) | namespace openage::renderer {

FILE: libopenage/renderer/renderer.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/renderer/resources/animation/angle_info.cpp
  type openage::renderer::resources (line 5) | namespace openage::renderer::resources {
    function flip_type (line 24) | const flip_type &AngleInfo::get_mirror_type() {

FILE: libopenage/renderer/resources/animation/angle_info.h
  function namespace (line 9) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/animation/animation_info.cpp
  type openage::renderer::resources (line 10) | namespace openage::renderer::resources {
    function LayerInfo (line 64) | const LayerInfo &Animation2dInfo::get_layer(size_t idx) const {

FILE: libopenage/renderer/resources/animation/animation_info.h
  function namespace (line 13) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/animation/frame_info.cpp
  type openage::renderer::resources (line 5) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/animation/frame_info.h
  function namespace (line 7) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/animation/layer_info.cpp
  type openage::renderer::resources (line 13) | namespace openage::renderer::resources {
    function display_mode (line 40) | display_mode LayerInfo::get_display_mode() const {

FILE: libopenage/renderer/resources/animation/layer_info.h
  function namespace (line 9) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/assets/asset_manager.cpp
  type openage::renderer::resources (line 25) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/assets/asset_manager.h
  function namespace (line 13) | namespace openage::renderer {

FILE: libopenage/renderer/resources/assets/cache.cpp
  type openage::renderer::resources (line 8) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/assets/cache.h
  function namespace (line 12) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/assets/texture_manager.cpp
  type openage::renderer::resources (line 9) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/assets/texture_manager.h
  function namespace (line 14) | namespace openage::renderer {

FILE: libopenage/renderer/resources/buffer_info.cpp
  type openage::renderer::resources (line 5) | namespace openage::renderer::resources {
    function ubo_layout_t (line 19) | ubo_layout_t UniformBufferInfo::get_layout() const {

FILE: libopenage/renderer/resources/buffer_info.h
  function namespace (line 14) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/frame_timing.cpp
  type openage::renderer::resources (line 14) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/frame_timing.h
  function namespace (line 11) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/mesh_data.cpp
  type openage::renderer::resources (line 16) | namespace openage::renderer::resources {
    function vertex_input_size (line 30) | size_t vertex_input_size(vertex_input_t in) {
    function vertex_input_count (line 34) | size_t vertex_input_count(vertex_input_t in) {
    function vertex_layout_t (line 77) | vertex_layout_t VertexInputInfo::get_layout() const {
    function vertex_primitive_t (line 81) | vertex_primitive_t VertexInputInfo::get_primitive() const {
    function VertexInputInfo (line 108) | VertexInputInfo MeshData::get_info() const {
    function MeshData (line 147) | MeshData create_float_mesh(const std::array<float, size> &src) {
    function MeshData (line 164) | MeshData MeshData::make_quad(bool centered) {
    function MeshData (line 174) | MeshData MeshData::make_quad(float sidelength, bool centered) {
    function MeshData (line 211) | MeshData MeshData::make_quad(float width, float height, bool centered) {

FILE: libopenage/renderer/resources/mesh_data.h
  function namespace (line 13) | namespace util {
  type class (line 20) | enum class
  type class (line 28) | enum class
  function index_t (line 39) | enum class index_t {

FILE: libopenage/renderer/resources/palette_info.cpp
  type openage::renderer::resources (line 5) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/palette_info.h
  function namespace (line 12) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/parser/common.cpp
  type openage::renderer::resources::parser (line 8) | namespace openage::renderer::resources::parser {
    function parse_version (line 10) | size_t parse_version(const std::vector<std::string> &args) {
    function TextureData (line 14) | TextureData parse_texture(const std::vector<std::string> &args) {
    function parse_scalefactor (line 28) | float parse_scalefactor(const std::vector<std::string> &args) {

FILE: libopenage/renderer/resources/parser/common.h
  function namespace (line 13) | namespace openage::renderer::resources::parser {

FILE: libopenage/renderer/resources/parser/parse_blendmask.cpp
  type openage::renderer::resources::parser (line 26) | namespace openage::renderer::resources::parser {
    function blending_mask (line 36) | blending_mask parse_mask(const std::vector<std::string> &args) {
    function BlendPatternInfo (line 61) | BlendPatternInfo parse_blendmask_file(const util::Path &path,

FILE: libopenage/renderer/resources/parser/parse_blendmask.h
  function namespace (line 10) | namespace openage {

FILE: libopenage/renderer/resources/parser/parse_blendtable.cpp
  type openage::renderer::resources::parser (line 24) | namespace openage::renderer::resources::parser {
    function parse_table (line 35) | std::vector<size_t> parse_table(const std::vector<std::string> &lines) {
    function PatternData (line 56) | PatternData parse_pattern(const std::vector<std::string> &args) {
    function BlendTableInfo (line 70) | BlendTableInfo parse_blendtable_file(const util::Path &path,

FILE: libopenage/renderer/resources/parser/parse_blendtable.h
  function namespace (line 11) | namespace openage {

FILE: libopenage/renderer/resources/parser/parse_palette.cpp
  type openage::renderer::resources::parser (line 23) | namespace openage::renderer::resources::parser {
    function parse_entries (line 33) | size_t parse_entries(const std::vector<std::string> &args) {
    function parse_colours (line 46) | std::vector<uint8_t> parse_colours(const std::vector<std::string> &lin...
    function PaletteInfo (line 66) | PaletteInfo parse_palette_file(const util::Path &path) {

FILE: libopenage/renderer/resources/parser/parse_palette.h
  function namespace (line 7) | namespace openage {

FILE: libopenage/renderer/resources/parser/parse_sprite.cpp
  type openage::renderer::resources::parser (line 28) | namespace openage::renderer::resources::parser {
    function LayerData (line 38) | LayerData parse_layer(const std::vector<std::string> &args) {
    function AngleData (line 90) | AngleData parse_angle(const std::vector<std::string> &args) {
    function FrameData (line 125) | FrameData parse_frame(const std::vector<std::string> &args) {
    function Animation2dInfo (line 137) | Animation2dInfo parse_sprite_file(const util::Path &path,

FILE: libopenage/renderer/resources/parser/parse_sprite.h
  function namespace (line 12) | namespace openage {

FILE: libopenage/renderer/resources/parser/parse_terrain.cpp
  type openage::renderer::resources::parser (line 29) | namespace openage::renderer::resources::parser {
    function BlendtableData (line 39) | BlendtableData parse_blendtable(const std::vector<std::string> &args) {
    function TerrainLayerData (line 61) | TerrainLayerData parse_terrain_layer(const std::vector<std::string> &a...
    function TerrainFrameData (line 110) | TerrainFrameData parse_terrain_frame(const std::vector<std::string> &a...
    function TerrainInfo (line 142) | TerrainInfo parse_terrain_file(const util::Path &path,

FILE: libopenage/renderer/resources/parser/parse_terrain.h
  function namespace (line 14) | namespace openage {

FILE: libopenage/renderer/resources/parser/parse_texture.cpp
  type openage::renderer::resources::parser (line 24) | namespace openage::renderer::resources::parser {
    function guess_row_alignment (line 29) | static constexpr size_t guess_row_alignment(size_t width) {
    function parse_imagefile (line 53) | std::string parse_imagefile(const std::vector<std::string> &args) {
    function SizeData (line 70) | SizeData parse_size(const std::vector<std::string> &args) {
    function PixelFormatData (line 87) | PixelFormatData parse_pxformat(const std::vector<std::string> &args) {
    function SubtextureData (line 129) | SubtextureData parse_subtex(const std::vector<std::string> &args) {
    function Texture2dInfo (line 142) | Texture2dInfo parse_texture_file(const util::Path &path) {

FILE: libopenage/renderer/resources/parser/parse_texture.h
  function namespace (line 10) | namespace openage {

FILE: libopenage/renderer/resources/shader_source.cpp
  type openage (line 11) | namespace openage {
    type renderer (line 12) | namespace renderer {
      type resources (line 13) | namespace resources {
        function shader_lang_t (line 25) | shader_lang_t ShaderSource::get_lang() const {
        function shader_stage_t (line 29) | shader_stage_t ShaderSource::get_stage() const {

FILE: libopenage/renderer/resources/shader_source.h
  function namespace (line 9) | namespace util {
  function namespace (line 13) | namespace resources {

FILE: libopenage/renderer/resources/shader_template.cpp
  type openage::renderer::resources (line 10) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/shader_template.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/renderer/resources/terrain/blendpattern_info.cpp
  type openage::renderer::resources (line 5) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/terrain/blendpattern_info.h
  function namespace (line 12) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/terrain/blendtable_info.cpp
  type openage::renderer::resources (line 5) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/terrain/blendtable_info.h
  function namespace (line 9) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/terrain/frame_info.cpp
  type openage::renderer::resources (line 5) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/terrain/frame_info.h
  function namespace (line 8) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/terrain/layer_info.cpp
  type openage::renderer::resources (line 12) | namespace openage::renderer::resources {
    function terrain_display_mode (line 37) | terrain_display_mode TerrainLayerInfo::get_display_mode() const {

FILE: libopenage/renderer/resources/terrain/layer_info.h
  function namespace (line 10) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/terrain/terrain_info.cpp
  type openage::renderer::resources (line 12) | namespace openage::renderer::resources {
    function TerrainLayerInfo (line 43) | const TerrainLayerInfo &TerrainInfo::get_layer(size_t idx) const {

FILE: libopenage/renderer/resources/terrain/terrain_info.h
  function namespace (line 12) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/texture_data.cpp
  type openage::renderer::resources (line 19) | namespace openage::renderer::resources {
    function guess_row_alignment (line 26) | static constexpr size_t guess_row_alignment(size_t width, pixel_format...
    function Texture2dData (line 128) | Texture2dData Texture2dData::flip_y() {
    function Texture2dInfo (line 145) | const Texture2dInfo &Texture2dData::get_info() const {

FILE: libopenage/renderer/resources/texture_data.h
  function namespace (line 16) | namespace openage {

FILE: libopenage/renderer/resources/texture_info.cpp
  type openage::renderer::resources (line 11) | namespace openage::renderer::resources {
    function pixel_format (line 41) | pixel_format Texture2dInfo::get_format() const {
    function Texture2dSubInfo (line 74) | const Texture2dSubInfo &Texture2dInfo::get_subtex_info(size_t subidx) ...

FILE: libopenage/renderer/resources/texture_info.h
  function namespace (line 17) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/texture_subinfo.cpp
  type openage::renderer::resources (line 6) | namespace openage::renderer::resources {

FILE: libopenage/renderer/resources/texture_subinfo.h
  function namespace (line 9) | namespace openage::renderer::resources {

FILE: libopenage/renderer/shader_program.h
  function namespace (line 17) | namespace openage {

FILE: libopenage/renderer/stages/camera/manager.cpp
  type openage::renderer::camera (line 11) | namespace openage::renderer::camera {

FILE: libopenage/renderer/stages/camera/manager.h
  function MoveDirection (line 17) | enum class MoveDirection {

FILE: libopenage/renderer/stages/hud/object.cpp
  type openage::renderer::hud (line 9) | namespace openage::renderer::hud {

FILE: libopenage/renderer/stages/hud/object.h
  function namespace (line 15) | namespace openage::renderer {

FILE: libopenage/renderer/stages/hud/render_entity.cpp
  type openage::renderer::hud (line 8) | namespace openage::renderer::hud {

FILE: libopenage/renderer/stages/hud/render_entity.h
  function namespace (line 12) | namespace openage::renderer::hud {

FILE: libopenage/renderer/stages/hud/render_stage.cpp
  type openage::renderer::hud (line 19) | namespace openage::renderer::hud {

FILE: libopenage/renderer/stages/hud/render_stage.h
  function namespace (line 11) | namespace openage {

FILE: libopenage/renderer/stages/render_entity.cpp
  type openage::renderer (line 8) | namespace openage::renderer {

FILE: libopenage/renderer/stages/render_entity.h
  function namespace (line 13) | namespace openage::renderer {

FILE: libopenage/renderer/stages/screen/render_stage.cpp
  type openage::renderer::screen (line 18) | namespace openage::renderer::screen {

FILE: libopenage/renderer/stages/screen/render_stage.h
  function namespace (line 10) | namespace openage::renderer {

FILE: libopenage/renderer/stages/screen/screenshot.cpp
  type openage::renderer::screen (line 23) | namespace openage::renderer::screen {

FILE: libopenage/renderer/stages/screen/screenshot.h
  function namespace (line 12) | namespace openage {

FILE: libopenage/renderer/stages/skybox/render_stage.cpp
  type openage::renderer::skybox (line 17) | namespace openage::renderer::skybox {

FILE: libopenage/renderer/stages/skybox/render_stage.h
  function namespace (line 11) | namespace openage::renderer {

FILE: libopenage/renderer/stages/terrain/chunk.cpp
  type openage::renderer::terrain (line 11) | namespace openage::renderer::terrain {

FILE: libopenage/renderer/stages/terrain/chunk.h
  function namespace (line 15) | namespace openage::renderer {

FILE: libopenage/renderer/stages/terrain/mesh.cpp
  type openage::renderer::terrain (line 16) | namespace openage::renderer::terrain {

FILE: libopenage/renderer/stages/terrain/mesh.h
  function namespace (line 16) | namespace openage::renderer {

FILE: libopenage/renderer/stages/terrain/model.cpp
  type openage::renderer::terrain (line 21) | namespace openage::renderer::terrain {

FILE: libopenage/renderer/stages/terrain/model.h
  function namespace (line 13) | namespace openage::renderer {

FILE: libopenage/renderer/stages/terrain/render_entity.cpp
  type openage::renderer::terrain (line 10) | namespace openage::renderer::terrain {

FILE: libopenage/renderer/stages/terrain/render_entity.h
  function namespace (line 16) | namespace openage::renderer::terrain {

FILE: libopenage/renderer/stages/terrain/render_stage.cpp
  type openage::renderer::terrain (line 20) | namespace openage::renderer::terrain {

FILE: libopenage/renderer/stages/terrain/render_stage.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/renderer/stages/world/object.cpp
  type openage::renderer::world (line 31) | namespace openage::renderer::world {

FILE: libopenage/renderer/stages/world/object.h
  function namespace (line 19) | namespace openage::renderer {

FILE: libopenage/renderer/stages/world/render_entity.cpp
  type openage::renderer::world (line 11) | namespace openage::renderer::world {

FILE: libopenage/renderer/stages/world/render_entity.h
  function namespace (line 16) | namespace openage::renderer::world {

FILE: libopenage/renderer/stages/world/render_stage.cpp
  type openage::renderer::world (line 20) | namespace openage::renderer::world {

FILE: libopenage/renderer/stages/world/render_stage.h
  function namespace (line 11) | namespace openage {

FILE: libopenage/renderer/texture.cpp
  type openage (line 9) | namespace openage {
    type renderer (line 10) | namespace renderer {

FILE: libopenage/renderer/texture.h
  function namespace (line 8) | namespace openage {

FILE: libopenage/renderer/texture_array.cpp
  type openage (line 6) | namespace openage {
    type renderer (line 7) | namespace renderer {

FILE: libopenage/renderer/texture_array.h
  function namespace (line 11) | namespace openage {

FILE: libopenage/renderer/types.cpp
  type openage::renderer (line 6) | namespace openage::renderer {

FILE: libopenage/renderer/types.h
  function namespace (line 8) | namespace openage::renderer {

FILE: libopenage/renderer/uniform_buffer.h
  function namespace (line 13) | namespace openage::renderer {

FILE: libopenage/renderer/uniform_input.cpp
  type openage::renderer (line 9) | namespace openage::renderer {

FILE: libopenage/renderer/uniform_input.h
  function namespace (line 16) | namespace openage::renderer {
  function update (line 183) | void update() override;

FILE: libopenage/renderer/util.cpp
  type openage::renderer::util (line 8) | namespace openage::renderer::util {
    function ortho_matrix_d (line 10) | Eigen::Matrix4d ortho_matrix_d(double left, double right, double botto...
    function ortho_matrix_f (line 15) | Eigen::Matrix4f ortho_matrix_f(float left, float right, float bottom, ...

FILE: libopenage/renderer/util.h
  function namespace (line 9) | namespace openage::renderer::util {

FILE: libopenage/renderer/vulkan/graphics_device.cpp
  type openage::renderer::vulkan (line 14) | namespace openage::renderer::vulkan {
    function VkPhysicalDevice (line 153) | VkPhysicalDevice VlkGraphicsDevice::get_physical_device() const {
    function VkDevice (line 157) | VkDevice VlkGraphicsDevice::get_device() const {
    function VkQueue (line 161) | VkQueue VlkGraphicsDevice::get_queue(size_t idx) const {

FILE: libopenage/renderer/vulkan/graphics_device.h
  function namespace (line 11) | namespace openage {

FILE: libopenage/renderer/vulkan/loader.cpp
  type openage (line 8) | namespace openage {
    type renderer (line 9) | namespace renderer {
      type vulkan (line 10) | namespace vulkan {
        function VkResult (line 25) | VkResult VlkLoader::vkCreateDebugReportCallbackEXT(

FILE: libopenage/renderer/vulkan/loader.h
  function namespace (line 8) | namespace openage {

FILE: libopenage/renderer/vulkan/render_target.h
  function namespace (line 16) | namespace openage {

FILE: libopenage/renderer/vulkan/renderer.cpp
  type openage::renderer::vulkan (line 16) | namespace openage::renderer::vulkan {

FILE: libopenage/renderer/vulkan/renderer.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/renderer/vulkan/shader_program.h
  function namespace (line 16) | namespace vulkan {

FILE: libopenage/renderer/vulkan/windowvk.cpp
  type openage::renderer::vulkan (line 19) | namespace openage::renderer::vulkan {
    function VKAPI_ATTR (line 22) | static VKAPI_ATTR VkBool32 VKAPI_CALL vlk_debug_cb(
    function vlk_spec (line 38) | static vlk_spec find_spec() {
    function VkInstance (line 180) | VkInstance VlkWindow::get_instance() const {
    function VkSurfaceKHR (line 185) | VkSurfaceKHR VlkWindow::get_surface() const {

FILE: libopenage/renderer/vulkan/windowvk.h
  function namespace (line 15) | QT_FORWARD_DECLARE_CLASS(QWindow)

FILE: libopenage/renderer/window.cpp
  type openage::renderer (line 11) | namespace openage::renderer {

FILE: libopenage/renderer/window.h
  function QT_FORWARD_DECLARE_CLASS (line 15) | QT_FORWARD_DECLARE_CLASS(QWindow)

FILE: libopenage/renderer/window_event_handler.cpp
  type openage::renderer (line 10) | namespace openage::renderer {

FILE: libopenage/renderer/window_event_handler.h
  function namespace (line 8) | namespace openage::renderer {

FILE: libopenage/rng/global_rng.cpp
  type openage (line 7) | namespace openage {
    type rng (line 8) | namespace rng {
      function global_seed (line 13) | uint64_t global_seed() {
      function random (line 18) | uint64_t random() {
      function random_range (line 23) | uint64_t random_range(uint64_t lower, uint64_t upper) {
      function real (line 28) | double real() {
      function real_range (line 33) | double real_range(double lower, double upper) {

FILE: libopenage/rng/global_rng.h
  function namespace (line 16) | namespace openage {

FILE: libopenage/rng/rng.cpp
  type openage::rng (line 20) | namespace openage::rng {
    function do_rng (line 78) | static inline uint64_t do_rng(uint64_t &s0, uint64_t &s1) {
    function act_fill (line 96) | static inline void act_fill(T *dat, uint64_t *state,
    function try_random_device (line 187) | static uint64_t try_random_device() {
    function time_seed (line 203) | static uint64_t time_seed(bool randomize) {
    function time_seed (line 213) | uint64_t time_seed() {
    function random_seed (line 218) | uint64_t random_seed() {

FILE: libopenage/rng/rng.h
  function namespace (line 9) | namespace openage::rng {

FILE: libopenage/rng/rng_tests.cpp
  type openage::rng::tests (line 13) | namespace openage::rng::tests {
    function freq_dist (line 34) | void freq_dist() {
    function bool_dist (line 82) | void bool_dist() {
    function real_dist (line 106) | void real_dist() {
    function reproduce (line 141) | void reproduce() {
    function serialize (line 173) | void serialize() {
    function fill (line 192) | void fill() {
    function fill_real (line 214) | void fill_real() {
    function run (line 231) | void run() {

FILE: libopenage/testing/benchmark_test.cpp
  type openage (line 6) | namespace openage {
    type test (line 7) | namespace test {
      function benchmark (line 9) | void benchmark() {

FILE: libopenage/testing/testing.cpp
  type openage (line 5) | namespace openage {
    type testing (line 6) | namespace testing {
      function fail (line 9) | bool fail(const log::message &msg) {

FILE: libopenage/testing/testing.h
  function namespace (line 7) | namespace openage {

FILE: libopenage/testing/testlist.h
  function namespace (line 12) | namespace openage {

FILE: libopenage/time/clock.cpp
  type openage::time (line 10) | namespace openage::time {
    function ClockState (line 22) | ClockState Clock::get_state() {
    function speed_t (line 67) | speed_t Clock::get_speed() {

FILE: libopenage/time/clock.h
  function namespace (line 11) | namespace openage::time {

FILE: libopenage/time/time.cpp
  type openage::time (line 6) | namespace openage::time {

FILE: libopenage/time/time.h
  function namespace (line 10) | namespace openage::time {

FILE: libopenage/time/time_loop.cpp
  type openage::time (line 11) | namespace openage::time {

FILE: libopenage/time/time_loop.h
  function namespace (line 9) | namespace openage::time {

FILE: libopenage/util/algorithm.h
  function namespace (line 10) | namespace openage {

FILE: libopenage/util/color.cpp
  type openage::util (line 7) | namespace openage::util {

FILE: libopenage/util/color.h
  function namespace (line 6) | namespace openage {

FILE: libopenage/util/compiler.cpp
  type openage (line 21) | namespace openage {
    type util (line 22) | namespace util {
      function demangle (line 25) | std::string demangle(const char *symbol) {
      function addr_to_string (line 47) | std::string addr_to_string(const void *addr) {
      function symbol_name_win (line 58) | std::optional<std::string> symbol_name_win(const void *addr) {
      function symbol_name (line 99) | std::string symbol_name(const void *addr, bool require_exact_addr, b...
      function is_symbol (line 138) | bool is_symbol(const void *addr) {

FILE: libopenage/util/compiler.h
  type __int64 (line 38) | typedef __int64 ssize_t;
  function namespace (line 72) | namespace openage {

FILE: libopenage/util/compress/bitstream.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/util/compress/lzxd.cpp
  type openage::util::compress (line 31) | namespace openage::util::compress {
    class HuffmanTable (line 85) | class HuffmanTable {
      class LZXDStream (line 87) | class LZXDStream
      method HuffmanTable (line 114) | explicit HuffmanTable(class LZXDStream *lzx) :
    class LZXDStream (line 147) | class LZXDStream {
      method LZXDStream (line 183) | LZXDStream(const LZXDStream &other) = delete;
      method LZXDStream (line 184) | LZXDStream(LZXDStream &&other) = delete;
      method LZXDStream (line 185) | LZXDStream &operator=(const LZXDStream &other) = delete;
      method LZXDStream (line 186) | LZXDStream &operator=(LZXDStream &&other) = delete;

FILE: libopenage/util/compress/lzxd.h
  function namespace (line 10) | namespace openage {

FILE: libopenage/util/consteval.h
  function namespace (line 12) | namespace openage::util::consteval_ {

FILE: libopenage/util/constinit_vector.cpp
  type openage (line 7) | namespace openage {
    type util (line 8) | namespace util {
      type tests (line 9) | namespace tests {
        type S (line 16) | struct S {
        class T (line 21) | class T {
          method T (line 23) | explicit T(int *ref)
          method T (line 36) | T(const T &other) : ref{other.ref} {
          method T (line 40) | T &operator =(const T &other) {
        function constinit_vector (line 55) | void constinit_vector() {

FILE: libopenage/util/constinit_vector.h
  function namespace (line 10) | namespace openage {

FILE: libopenage/util/enum.cpp
  type openage (line 5) | namespace openage {
    type util (line 6) | namespace util {

FILE: libopenage/util/enum.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/util/enum_test.cpp
  type openage (line 8) | namespace openage {
    type util (line 9) | namespace util {
      type tests (line 10) | namespace tests {
        function enum_ (line 15) | void enum_() {

FILE: libopenage/util/enum_test.h
  function testenum_value (line 20) | struct OAAPI testenum_value : EnumValue<testenum_value> {
  type OAAPI (line 37) | struct OAAPI
  function testenum_value (line 47) | static constexpr testenum_value foo{{"foo", 1}, "foooooooooooooooooo"};

FILE: libopenage/util/externalprofiler.cpp
  type openage (line 18) | namespace openage {
    type util (line 19) | namespace util {

FILE: libopenage/util/externalprofiler.h
  function namespace (line 5) | namespace openage {

FILE: libopenage/util/externalsstream.cpp
  type openage (line 5) | namespace openage {
    type util (line 6) | namespace util {

FILE: libopenage/util/externalsstream.h
  function namespace (line 8) | namespace openage {

FILE: libopenage/util/fds.cpp
  type openage::util (line 20) | namespace openage::util {
    type termios (line 119) | struct termios

FILE: libopenage/util/fds.h
  function namespace (line 11) | namespace openage {

FILE: libopenage/util/file.cpp
  type openage::util (line 22) | namespace openage::util {
    function File (line 125) | File File::get_temp_file(bool executable) {

FILE: libopenage/util/file.h
  function namespace (line 18) | namespace openage {

FILE: libopenage/util/filelike/filelike.cpp
  type openage::util::filelike (line 5) | namespace openage::util::filelike {

FILE: libopenage/util/filelike/filelike.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/util/filelike/native.cpp
  type openage::util::filelike (line 10) | namespace openage::util::filelike {

FILE: libopenage/util/filelike/native.h
  function namespace (line 13) | namespace openage {

FILE: libopenage/util/filelike/python.cpp
  type openage::util::filelike (line 8) | namespace openage::util::filelike {

FILE: libopenage/util/filelike/python.h
  function namespace (line 20) | namespace openage {

FILE: libopenage/util/fixed_point.cpp
  type openage (line 5) | namespace openage {
    type util (line 6) | namespace util {

FILE: libopenage/util/fixed_point.h
  function namespace (line 17) | namespace openage {
  function typename (line 124) | static constexpr typename FixedPoint::unsigned_int_type fractional_part_...
  function int_type (line 134) | static constexpr int_type raw_value_from_double(double n) {
  function raw_value (line 143) | constexpr FixedPoint(FixedPoint &&other) noexcept
  function log10e (line 160) | constexpr FixedPoint() :
  function FixedPoint (line 194) | static constexpr FixedPoint ln2() {
  function FixedPoint (line 198) | static constexpr FixedPoint ln10() {
  function FixedPoint (line 202) | static constexpr FixedPoint pi() {
  function FixedPoint (line 206) | static constexpr FixedPoint pi_2() {
  function FixedPoint (line 210) | static constexpr FixedPoint pi_4() {
  function FixedPoint (line 214) | static constexpr FixedPoint inv_pi() {
  function FixedPoint (line 218) | static constexpr FixedPoint inv2_pi() {
  function FixedPoint (line 222) | static constexpr FixedPoint inv2_sqrt_pi() {
  function FixedPoint (line 226) | static constexpr FixedPoint tau() {
  function FixedPoint (line 230) | static constexpr FixedPoint degs_per_rad() {
  function FixedPoint (line 234) | static constexpr FixedPoint rads_per_deg() {
  function FixedPoint (line 238) | static constexpr FixedPoint sqrt_2() {
  function FixedPoint (line 242) | static constexpr FixedPoint inv_sqrt_2() {
  function FixedPoint (line 249) | static constexpr FixedPoint from_int(int_type n) {
  function FixedPoint (line 256) | static constexpr FixedPoint from_float(float n) {
  function FixedPoint (line 263) | static constexpr FixedPoint from_double(double n) {
  function FixedPoint (line 271) | constexpr FixedPoint from_fixedpoint(const FixedPoint<other_int_type, ot...
  function FixedPoint (line 277) | constexpr FixedPoint from_fixedpoint(const FixedPoint<other_int_type, ot...
  function FixedPoint (line 285) | static constexpr const FixedPoint min_value() {
  function FixedPoint (line 292) | static constexpr const FixedPoint max_value() {
  function FixedPoint (line 300) | static constexpr FixedPoint from_raw_value(int_type raw_value) {
  function sin (line 502) | constexpr double sin() {
  function cos (line 506) | constexpr double cos() {
  function tan (line 510) | constexpr double tan() {
  function namespace (line 618) | namespace std {
  function hypot (line 666) | constexpr double hypot(openage::util::FixedPoint<I, F, Inter> x, openage...
  type hash (line 671) | struct hash
  function const (line 672) | constexpr size_t operator()(const openage::util::FixedPoint<I, F, Inter>...
  type numeric_limits (line 678) | struct numeric_limits

FILE: libopenage/util/fixed_point_test.cpp
  type openage (line 11) | namespace openage {
    type util (line 12) | namespace util {
      type tests (line 13) | namespace tests {
        function fixed_point (line 16) | void fixed_point() {

FILE: libopenage/util/fps.cpp
  type openage::util (line 9) | namespace openage::util {

FILE: libopenage/util/fps.h
  function namespace (line 7) | namespace openage {

FILE: libopenage/util/fslike/directory.cpp
  type openage::util::fslike (line 42) | namespace openage::util::fslike {
    type stat (line 67) | struct stat
    type stat (line 69) | struct stat
    type dirent (line 122) | struct dirent
    type stat (line 151) | struct stat
    function File (line 175) | File Directory::open_r(const Path::parts_t &parts) {
    function File (line 182) | File Directory::open_w(const Path::parts_t &parts) {
    function File (line 189) | File Directory::open_rw(const Path::parts_t &parts) {
    function File (line 196) | File Directory::open_a(const Path::parts_t &parts) {
    function File (line 203) | File Directory::open_ar(const Path::parts_t &parts) {
    function Directory (line 296) | Directory Directory::get_temp_directory() {

FILE: libopenage/util/fslike/directory.h
  function namespace (line 14) | namespace openage {

FILE: libopenage/util/fslike/fslike.cpp
  type openage::util::fslike (line 8) | namespace openage::util::fslike {
    function Path (line 12) | Path FSLike::root() {

FILE: libopenage/util/fslike/fslike.h
  function namespace (line 25) | namespace openage {

FILE: libopenage/util/fslike/native.cpp
  type openage (line 6) | namespace openage {
    type util (line 7) | namespace util {
      type fslike (line 8) | namespace fslike {

FILE: libopenage/util/fslike/native.h
  function namespace (line 6) | namespace openage {

FILE: libopenage/util/fslike/python.cpp
  type openage::util::fslike (line 7) | namespace openage::util::fslike {
    function File (line 35) | File Python::open_r(const Path::parts_t &parts) {
    function File (line 39) | File Python::open_w(const Path::parts_t &parts) {
    function File (line 43) | File Python::open_rw(const Path::parts_t &parts) {
    function File (line 47) | File Python::open_a(const Path::parts_t &parts) {
    function File (line 51) | File Python::open_ar(const Path::parts_t &parts) {

FILE: libopenage/util/fslike/python.h
  function namespace (line 28) | namespace openage {

FILE: libopenage/util/hash.cpp
  type openage::util (line 9) | namespace openage::util {
    function hash_combine (line 11) | size_t hash_combine(size_t hash1, size_t hash2) {
    function Siphash (line 22) | Siphash& Siphash::set_key(std::array<uint8_t, 16> key) {
    function hash (line 35) | uint64_t hash(const uint64_t key[2], const uint8_t *data, size_t len_d...

FILE: libopenage/util/hash.h
  function namespace (line 11) | namespace openage {

FILE: libopenage/util/hash_test.cpp
  type openage::util::tests (line 11) | namespace openage::util::tests {
    function siphash (line 19) | void siphash() {

FILE: libopenage/util/init.cpp
  type openage (line 7) | namespace openage {
    type util (line 8) | namespace util {
      type tests (line 9) | namespace tests {
        function init (line 20) | void init() {

FILE: libopenage/util/init.h
  function namespace (line 7) | namespace openage {

FILE: libopenage/util/language.h
  function namespace (line 11) | namespace openage {

FILE: libopenage/util/math.h
  function namespace (line 7) | namespace openage {

FILE: libopenage/util/math_constants.h
  function namespace (line 8) | namespace openage {

FILE: libopenage/util/matrix.cpp
  type openage (line 5) | namespace openage {
    type util (line 6) | namespace util {

FILE: libopenage/util/matrix.h
  function namespace (line 13) | namespace openage::util {

FILE: libopenage/util/matrix_test.cpp
  type openage (line 8) | namespace openage {
    type util (line 9) | namespace util {
      type tests (line 10) | namespace tests {
        function matrix (line 12) | void matrix() {

FILE: libopenage/util/misc.cpp
  type openage (line 5) | namespace openage {
    type util (line 6) | namespace util {

FILE: libopenage/util/misc.h
  function namespace (line 17) | namespace openage::util {
  function array64_size (line 168) | inline constexpr size_t array64_size(size_t count) {

FILE: libopenage/util/misc_test.cpp
  type openage (line 8) | namespace openage {
    type util (line 9) | namespace util {
      type tests (line 10) | namespace tests {
        function array_conversion (line 13) | void array_conversion() {

FILE: libopenage/util/os.cpp
  type openage::os (line 25) | namespace openage::os {
    function read_symlink (line 27) | std::string read_symlink(const char *path) {
    function self_exec_filename (line 56) | std::string self_exec_filename() {
    function execute_file (line 100) | int execute_file(const char *path, bool background) {

FILE: libopenage/util/os.h
  function namespace (line 7) | namespace openage {

FILE: libopenage/util/path.cpp
  type openage::util (line 16) | namespace openage::util {
    function path_normalizer (line 22) | void path_normalizer(Path::parts_t &output, const Path::parts_t &input) {
    function File (line 108) | File Path::open(const std::string &mode) const {
    function File (line 130) | File Path::open_r() const {
    function File (line 135) | File Path::open_w() const {
    function File (line 140) | File Path::open_rw() const {
    function File (line 145) | File Path::open_a() const {
    function File (line 150) | File Path::open_ar() const {
    function Path (line 248) | Path Path::get_parent() const {
    function Path (line 294) | Path Path::joinpath(const parts_t &subpaths) const {
    function Path (line 304) | Path Path::joinpath(const part_t &subpath) const {
    function Path (line 308) | Path Path::operator[](const parts_t &subpaths) const {
    function Path (line 312) | Path Path::operator[](const part_t &subpath) const {
    function Path (line 316) | Path Path::operator/(const part_t &subpath) const {
    function Path (line 320) | Path Path::with_name(const part_t &name) const {
    function Path (line 324) | Path Path::with_suffix(const part_t &suffix) const {
    function filename (line 374) | std::string filename(const std::string &fullpath) {
    function dirname (line 385) | std::string dirname(const std::string &fullpath) {

FILE: libopenage/util/path.h
  function namespace (line 26) | namespace fslike {
  function is_file (line 87) | bool is_file() const;

FILE: libopenage/util/quaternion.cpp
  type openage (line 5) | namespace openage {
    type util (line 6) | namespace util {

FILE: libopenage/util/quaternion.h
  function this_type (line 146) | this_type q{
  function this_type (line 157) | static this_type from_deg(T deg, Vector3t<T> axis) {
  function T (line 164) | T dot(const this_type &o) const {
  function T (line 171) | T norm() const {
  function this_type (line 188) | this_type q{*this};
  function inverse (line 200) | void inverse() {
  function this_type (line 214) | this_type q{*this};
  function conjugate (line 223) | void conjugate() {
  function this_type (line 233) | this_type q{*this};
  function equals (line 241) | bool equals(const this_type &other, T eps = default_eps) const {
  function equals_number (line 249) | bool equals_number(const this_type &other, T eps = default_eps) const {
  function equals_rad (line 262) | bool equals_rad(const this_type &other, T rad_eps = default_eps) const {
  function equals_deg (line 273) | bool equals_deg(const this_type &other, T deg_eps = default_eps) const {
  function this_type (line 333) | this_type q{*this};
  function this_type (line 348) | this_type q{*this};
  function this_type (line 363) | this_type q{*this};
  function this_type (line 387) | this_type q{*this};
  function this_type (line 401) | this_type operator/(const T &fac) const {

FILE: libopenage/util/quaternion_test.cpp
  type openage::util::tests (line 12) | namespace openage::util::tests {
    function quaternion (line 14) | void quaternion() {

FILE: libopenage/util/repr.cpp
  type openage (line 5) | namespace openage {
    type util (line 6) | namespace util {
      function repr (line 12) | std::string repr(const std::string &arg) {

FILE: libopenage/util/repr.h
  function namespace (line 7) | namespace openage {

FILE: libopenage/util/stringformatter.cpp
  type openage::util (line 7) | namespace openage::util {
    function CachableOSStream (line 21) | CachableOSStream *CachableOSStream::acquire(std::string &output) {

FILE: libopenage/util/stringformatter.h
  function namespace (line 14) | namespace openage {

FILE: libopenage/util/strings.cpp
  type openage::util (line 16) | namespace openage::util {
    function sformat (line 19) | std::string sformat(const char *fmt, ...) {
    function vsformat (line 31) | size_t vsformat(const char *fmt, va_list ap, std::string &output) {
    function copy_string (line 63) | std::unique_ptr<char[]> copy_string(const char *s) {
    function rstrip (line 71) | size_t rstrip(char *s) {
    function string_matches_pattern (line 89) | bool string_matches_pattern(const char *str, const char *pattern) {
    function split (line 133) | std::vector<std::string> split(const std::string &txt, char delimiter) {
    function split_escape (line 141) | std::vector<std::string> split_escape(const std::string &txt, char del...
    function split_newline (line 209) | std::vector<std::string> split_newline(const std::string &txt) {

FILE: libopenage/util/strings.h
  function namespace (line 19) | namespace openage {

FILE: libopenage/util/subprocess.cpp
  type openage::subprocess (line 22) | namespace openage::subprocess {
    function is_executable (line 24) | bool is_executable(const char *filename) {
    function which (line 36) | std::string which(const char *name) {
    function call (line 71) | int call(const std::vector<const char *> &argv, bool wait, const char ...

FILE: libopenage/util/subprocess.h
  function namespace (line 8) | namespace openage {

FILE: libopenage/util/thread_id.cpp
  type openage (line 13) | namespace openage {
    type util (line 14) | namespace util {
      class ThreadIdSupplier (line 24) | class ThreadIdSupplier {
        method ThreadIdSupplier (line 26) | ThreadIdSupplier() :
      function get_current_thread_id (line 43) | size_t get_current_thread_id() {

FILE: libopenage/util/thread_id.h
  function namespace (line 7) | namespace openage {

FILE: libopenage/util/timer.cpp
  type openage (line 7) | namespace openage {
    type util (line 8) | namespace util {
      function time_nsec_t (line 37) | time_nsec_t Timer::getval() const {
      function time_nsec_t (line 45) | time_nsec_t Timer::getandresetval() {

FILE: libopenage/util/timer.h
  function namespace (line 10) | namespace openage {

FILE: libopenage/util/timing.cpp
  type openage (line 10) | namespace openage {
    type timing (line 11) | namespace timing {
      function time_nsec_t (line 13) | time_nsec_t get_real_time() {
      function time_nsec_t (line 20) | time_nsec_t get_monotonic_time() {

FILE: libopenage/util/timing.h
  function namespace (line 7) | namespace openage {

FILE: libopenage/util/unicode.cpp
  type openage (line 7) | namespace openage {
    type util (line 8) | namespace util {
      function utf8_decode (line 72) | size_t utf8_decode(const unsigned char *s, size_t len, int32_t *outb...
      function utf8_encode (line 120) | size_t utf8_encode(int cp, char *outbuf) {
      function utf8_last_char_size (line 154) | size_t utf8_last_char_size(char *str) {
      function utf8_pop_back (line 167) | void utf8_pop_back(std::string &str) {

FILE: libopenage/util/unicode.h
  function namespace (line 9) | namespace openage {

FILE: libopenage/util/variable.h
  function namespace (line 5) | namespace openage {

FILE: libopenage/util/vector.cpp
  type openage (line 5) | namespace openage {
    type util (line 6) | namespace util {

FILE: libopenage/util/vector.h
  function namespace (line 16) | namespace openage::util {
  function this_type (line 150) | this_type operator/(T a) const {
  function T (line 159) | T dot(const this_type &other) const {
  function T (line 170) | T norm() const {

FILE: libopenage/util/vector_test.cpp
  type openage (line 7) | namespace openage {
    type util (line 8) | namespace util {
      type tests (line 9) | namespace tests {
        function vector (line 11) | void vector() {

FILE: libopenage/versions/versions.cpp
  type openage::versions (line 19) | namespace openage::versions {
    function get_version_numbers (line 21) | std::map<std::string, std::string> get_version_numbers() {

FILE: libopenage/versions/versions.h
  function namespace (line 13) | namespace openage::versions {

FILE: openage/__main__.py
  function print_version (line 20) | def print_version():
  function add_dll_search_paths (line 34) | def add_dll_search_paths(dll_paths: list[str]):
  function main (line 45) | def main(argv=None):

FILE: openage/assets.py
  function get_asset_path (line 24) | def get_asset_path(custom_asset_dir: str = None) -> UnionPath:
  function test (line 69) | def test():

FILE: openage/cabextract/cab.py
  class CFHeaderFlags (line 31) | class CFHeaderFlags(Flags):
  class CFHeader (line 53) | class CFHeader(NamedStruct):
  class CFHeaderReservedFields (line 87) | class CFHeaderReservedFields(NamedStruct):
  class CFFolder (line 103) | class CFFolder(NamedStruct):
  class CFFileAttributes (line 125) | class CFFileAttributes(Flags):
  class CFFile (line 142) | class CFFile(NamedStruct):
  class CFData (line 180) | class CFData(NamedStruct):
    method verify_checksum (line 198) | def verify_checksum(self) -> Union[None, NoReturn]:
  class CABEntry (line 219) | class CABEntry(FileEntry):
    method __init__ (line 224) | def __init__(self, fileobj: CFFile):
    method open_r (line 227) | def open_r(self):
    method size (line 234) | def size(self) -> int:
    method mtime (line 237) | def mtime(self) -> float:
  class CABFile (line 241) | class CABFile(FileCollection):
    method __init__ (line 255) | def __init__(self, cab: FileLikeObject, offset: int = 0):
    method __repr__ (line 304) | def __repr__(self):
    method read_folder_headers (line 307) | def read_folder_headers(
    method read_file_headers (line 369) | def read_file_headers(self, cab: FileLikeObject, offset: int) -> Gener...
  class CABFolderStream (line 425) | class CABFolderStream(PosSavingReadOnlyFileLikeObject):
    method __init__ (line 450) | def __init__(
    method next_block_size (line 469) | def next_block_size(self, payloadsize: int) -> None:
    method read_block_data (line 479) | def read_block_data(self, block_id: int) -> bytes:
    method read_blocks (line 519) | def read_blocks(self, size: int = -1) -> Generator[bytes, None, None]:
    method read (line 566) | def read(self, size: int = -1) -> bytes:
    method get_size (line 569) | def get_size(self) -> int:
    method close (line 573) | def close(self) -> None:

FILE: openage/cabextract/lzxdstream.py
  class LZXDStream (line 18) | class LZXDStream(ReadOnlyFileLikeObject):
    method __init__ (line 42) | def __init__(self, sourcestream, window_bits=21, reset_interval=0):
    method reset (line 55) | def reset(self) -> None:
    method read (line 68) | def read(self, size: int = -1) -> bytes:
    method get_size (line 82) | def get_size(self) -> int:
    method seek (line 87) | def seek(self, offset: int, whence=os.SEEK_SET) -> NoReturn:
    method seekable (line 91) | def seekable(self) -> bool:
    method tell (line 94) | def tell(self) -> int:
    method close (line 97) | def close(self) -> None:

FILE: openage/cabextract/test.py
  function open_cached_test_archive (line 39) | def open_cached_test_archive():
  function open_test_archive (line 49) | def open_test_archive() -> BufferedReader:
  function test (line 65) | def test():

FILE: openage/codegen/codegen.py
  class CodegenMode (line 23) | class CodegenMode(Enum):
  class WriteCatcher (line 41) | class WriteCatcher(FIFO):
    method close (line 47) | def close(self) -> None:
    method read (line 50) | def read(self, size: int = -1) -> bytes:
  class CodegenDirWrapper (line 57) | class CodegenDirWrapper(Wrapper):
    method __init__ (line 66) | def __init__(self, obj):
    method open_r (line 75) | def open_r(self, parts):
    method open_w (line 79) | def open_w(self, parts):
    method get_reads (line 84) | def get_reads(self) -> None:
    method get_writes (line 94) | def get_writes(self) -> None:
    method __repr__ (line 104) | def __repr__(self):
  function codegen (line 108) | def codegen(mode: CodegenMode, input_dir: str, output_dir: str) -> tuple...
  function depend_module_blacklist (line 172) | def depend_module_blacklist():
  function get_codegen_depends (line 194) | def get_codegen_depends(outputwrapper: CodegenDirWrapper) -> Generator[s...
  function get_header_lines (line 242) | def get_header_lines() -> Generator[str, None, None]:
  function postprocess_write (line 258) | def postprocess_write(parts, data: str) -> str:

FILE: openage/codegen/coord.py
  function generate_coord_basetypes (line 10) | def generate_coord_basetypes(projectdir):

FILE: openage/codegen/cpp_testlist.py
  class Namespace (line 11) | class Namespace:
    method __init__ (line 18) | def __init__(self):
    method add_functionname (line 22) | def add_functionname(self, path):
    method gen_prototypes (line 37) | def gen_prototypes(self):
    method get_functionnames (line 51) | def get_functionnames(self):
  function generate_testlist (line 64) | def generate_testlist(projectdir):

FILE: openage/codegen/listing.py
  function generate_all (line 8) | def generate_all(projectdir):

FILE: openage/codegen/main.py
  function init_subparser (line 62) | def init_subparser(cli: ArgumentParser):
  function main (line 113) | def main(args, error):

FILE: openage/convert/entity_object/conversion/aoc/genie_civ.py
  class GenieCivilizationObject (line 22) | class GenieCivilizationObject(ConverterObject):
    method __init__ (line 29) | def __init__(
    method __repr__ (line 50) | def __repr__(self):
  class GenieCivilizationGroup (line 54) | class GenieCivilizationGroup(ConverterObjectGroup):
    method __init__ (line 64) | def __init__(
    method add_civ_bonus (line 113) | def add_civ_bonus(self, civ_bonus: CivBonus):
    method add_unique_entity (line 119) | def add_unique_entity(self, entity_group: GenieGameEntityGroup):
    method add_unique_tech (line 125) | def add_unique_tech(self, tech_group: GenieTechObject):
    method get_team_bonus_effects (line 131) | def get_team_bonus_effects(self) -> list[GenieEffectObject]:
    method get_tech_tree_effects (line 140) | def get_tech_tree_effects(self) -> list[GenieEffectObject]:
    method __repr__ (line 149) | def __repr__(self):

FILE: openage/convert/entity_object/conversion/aoc/genie_connection.py
  class GenieAgeConnection (line 19) | class GenieAgeConnection(ConverterObject):
    method __init__ (line 26) | def __init__(
    method __repr__ (line 46) | def __repr__(self):
  class GenieBuildingConnection (line 50) | class GenieBuildingConnection(ConverterObject):
    method __init__ (line 57) | def __init__(
    method __repr__ (line 77) | def __repr__(self):
  class GenieTechConnection (line 81) | class GenieTechConnection(ConverterObject):
    method __init__ (line 88) | def __init__(
    method __repr__ (line 108) | def __repr__(self):
  class GenieUnitConnection (line 112) | class GenieUnitConnection(ConverterObject):
    method __init__ (line 119) | def __init__(
    method __repr__ (line 139) | def __repr__(self):

FILE: openage/convert/entity_object/conversion/aoc/genie_effect.py
  class GenieEffectObject (line 18) | class GenieEffectObject(ConverterObject):
    method __init__ (line 25) | def __init__(
    method get_type (line 49) | def get_type(self) -> int:
    method __repr__ (line 55) | def __repr__(self):
  class GenieEffectBundle (line 59) | class GenieEffectBundle(ConverterObject):
    method __init__ (line 66) | def __init__(
    method get_effects (line 97) | def get_effects(self, effect_type: int = None) -> list[GenieEffectObje...
    method is_sanitized (line 117) | def is_sanitized(self) -> bool:
    method __repr__ (line 123) | def __repr__(self):

FILE: openage/convert/entity_object/conversion/aoc/genie_graphic.py
  class GenieGraphic (line 17) | class GenieGraphic(ConverterObject):
    method __init__ (line 24) | def __init__(
    method add_reference (line 56) | def add_reference(self, referer: GenieGraphic) -> None:
    method detect_subgraphics (line 62) | def detect_subgraphics(self) -> None:
    method get_animation_length (line 80) | def get_animation_length(self) -> float:
    method get_subgraphics (line 87) | def get_subgraphics(self) -> list[GenieGraphic]:
    method get_frame_rate (line 93) | def get_frame_rate(self) -> float:
    method is_shared (line 100) | def is_shared(self) -> bool:
    method __repr__ (line 106) | def __repr__(self):

FILE: openage/convert/entity_object/conversion/aoc/genie_object_container.py
  class GenieObjectContainer (line 42) | class GenieObjectContainer(ConverterObjectContainer):
    method __init__ (line 48) | def __init__(self):
    method __repr__ (line 125) | def __repr__(self):

FILE: openage/convert/entity_object/conversion/aoc/genie_sound.py
  class GenieSound (line 17) | class GenieSound(ConverterObject):
    method __init__ (line 24) | def __init__(
    method get_sounds (line 44) | def get_sounds(self, civ_id: int = -1) -> list[int]:
    method __repr__ (line 63) | def __repr__(self):

FILE: openage/convert/entity_object/conversion/aoc/genie_tech.py
  class GenieTechObject (line 21) | class GenieTechObject(ConverterObject):
    method __init__ (line 32) | def __init__(
    method __repr__ (line 52) | def __repr__(self):
  class GenieTechEffectBundleGroup (line 56) | class GenieTechEffectBundleGroup(ConverterObjectGroup):
    method __init__ (line 63) | def __init__(
    method is_researchable (line 91) | def is_researchable(self) -> bool:
    method is_unique (line 105) | def is_unique(self) -> bool:
    method get_civilization (line 116) | def get_civilization(self) -> typing.Union[int, None]:
    method get_effects (line 125) | def get_effects(self, effect_type: int = None) -> list[GenieEffectObje...
    method get_required_techs (line 134) | def get_required_techs(self) -> list[GenieTechObject]:
    method get_required_tech_count (line 151) | def get_required_tech_count(self) -> int:
    method get_research_location_id (line 157) | def get_research_location_id(self) -> int:
    method has_effect (line 167) | def has_effect(self) -> bool:
    method __repr__ (line 176) | def __repr__(self):
  class StatUpgrade (line 180) | class StatUpgrade(GenieTechEffectBundleGroup):
    method __repr__ (line 185) | def __repr__(self):
  class AgeUpgrade (line 189) | class AgeUpgrade(GenieTechEffectBundleGroup):
    method __init__ (line 201) | def __init__(
    method __repr__ (line 220) | def __repr__(self):
  class UnitLineUpgrade (line 224) | class UnitLineUpgrade(GenieTechEffectBundleGroup):
    method __init__ (line 233) | def __init__(
    method get_line_id (line 255) | def get_line_id(self) -> int:
    method get_upgraded_line (line 261) | def get_upgraded_line(self) -> GenieUnitLineGroup:
    method get_upgrade_target_id (line 267) | def get_upgrade_target_id(self) -> int:
    method __repr__ (line 273) | def __repr__(self):
  class BuildingLineUpgrade (line 277) | class BuildingLineUpgrade(GenieTechEffectBundleGroup):
    method __init__ (line 286) | def __init__(
    method get_line_id (line 308) | def get_line_id(self) -> int:
    method get_upgraded_line (line 314) | def get_upgraded_line(self) -> GenieBuildingLineGroup:
    method get_upgrade_target_id (line 320) | def get_upgrade_target_id(self) -> int:
    method __repr__ (line 326) | def __repr__(self):
  class UnitUnlock (line 330) | class UnitUnlock(GenieTechEffectBundleGroup):
    method __init__ (line 341) | def __init__(
    method get_line_id (line 361) | def get_line_id(self) -> int:
    method get_unlocked_line (line 367) | def get_unlocked_line(self) -> GenieUnitLineGroup:
    method __repr__ (line 373) | def __repr__(self):
  class BuildingUnlock (line 377) | class BuildingUnlock(GenieTechEffectBundleGroup):
    method __init__ (line 388) | def __init__(
    method get_line_id (line 408) | def get_line_id(self) -> int:
    method get_unlocked_line (line 414) | def get_unlocked_line(self) -> GenieBuildingLineGroup:
    method __repr__ (line 420) | def __repr__(self):
  class InitiatedTech (line 424) | class InitiatedTech(GenieTechEffectBundleGroup):
    method __init__ (line 433) | def __init__(
    method get_building_id (line 453) | def get_building_id(self) -> int:
    method __repr__ (line 459) | def __repr__(self):
  class CivBonus (line 463) | class CivBonus(GenieTechEffectBundleGroup):
    method __init__ (line 472) | def __init__(
    method get_civilization_id (line 492) | def get_civilization_id(self) -> int:
    method replaces_researchable_tech (line 498) | def replaces_researchable_tech(self) -> typing.Union[GenieTechEffectBu...
    method __repr__ (line 513) | def __repr__(self):
  class CivTeamBonus (line 517) | class CivTeamBonus(ConverterObjectGroup):
    method __init__ (line 526) | def __init__(
    method get_civilization_id (line 549) | def get_civilization_id(self) -> int:
    method get_effects (line 555) | def get_effects(self) -> list[GenieEffectObject]:
    method __repr__ (line 561) | def __repr__(self):
  class CivTechTree (line 565) | class CivTechTree(ConverterObjectGroup):
    method __init__ (line 574) | def __init__(
    method get_civilization_id (line 600) | def get_civilization_id(self):
    method get_effects (line 606) | def get_effects(self) -> list[GenieEffectObject]:
    method __repr__ (line 615) | def __repr__(self):

FILE: openage/convert/entity_object/conversion/aoc/genie_terrain.py
  class GenieTerrainObject (line 17) | class GenieTerrainObject(ConverterObject):
    method __init__ (line 24) | def __init__(
    method __repr__ (line 45) | def __repr__(self):
  class GenieTerrainGroup (line 49) | class GenieTerrainGroup(ConverterObjectGroup):
    method __init__ (line 56) | def __init__(
    method has_subterrain (line 77) | def has_subterrain(self) -> bool:
    method get_subterrain (line 83) | def get_subterrain(self) -> GenieTerrainObject:
    method get_terrain (line 89) | def get_terrain(self) -> GenieTerrainObject:
    method __repr__ (line 95) | def __repr__(self):
  class GenieTerrainRestriction (line 99) | class GenieTerrainRestriction(ConverterObject):
    method __init__ (line 106) | def __init__(
    method is_accessible (line 124) | def is_accessible(self, terrain_index: int) -> bool:
    method __repr__ (line 134) | def __repr__(self):

FILE: openage/convert/entity_object/conversion/aoc/genie_unit.py
  class GenieUnitObject (line 22) | class GenieUnitObject(ConverterObject):
    method __init__ (line 29) | def __init__(
    method __repr__ (line 49) | def __repr__(self):
  class GenieGameEntityGroup (line 53) | class GenieGameEntityGroup(ConverterObjectGroup):
    method __init__ (line 74) | def __init__(
    method add_creatable (line 115) | def add_creatable(self, line: GenieGameEntityGroup) -> None:
    method add_researchable (line 124) | def add_researchable(self, tech_group: GenieTechEffectBundleGroup) -> ...
    method add_unit (line 133) | def add_unit(
    method contains_creatable (line 175) | def contains_creatable(self, line_id: int) -> bool:
    method contains_entity (line 191) | def contains_entity(self, unit_id: int) -> bool:
    method contains_researchable (line 197) | def contains_researchable(self, line_id: int) -> bool:
    method has_armor (line 206) | def has_armor(self, armor_class: int) -> bool:
    method has_attack (line 224) | def has_attack(self, armor_class: int) -> bool:
    method has_command (line 242) | def has_command(self, command_id: int, civ_id: int = -1) -> bool:
    method has_projectile (line 266) | def has_projectile(self, projectile_id: int, civ_id: int = -1) -> bool:
    method is_creatable (line 288) | def is_creatable(self, civ_id: int = -1) -> bool:
    method is_harvestable (line 307) | def is_harvestable(self, civ_id: int = -1) -> bool:
    method is_garrison (line 329) | def is_garrison(self, civ_id: int = -1) -> bool:
    method is_gatherer (line 370) | def is_gatherer(self, civ_id: int = -1) -> bool:
    method is_passable (line 381) | def is_passable(self, civ_id: int = -1) -> bool:
    method is_projectile_shooter (line 396) | def is_projectile_shooter(self, civ_id: int = -1) -> bool:
    method is_ranged (line 423) | def is_ranged(self, civ_id: int = -1) -> bool:
    method is_melee (line 438) | def is_melee(self, civ_id: int = -1) -> bool:
    method is_repairable (line 449) | def is_repairable(self) -> bool:
    method is_unique (line 457) | def is_unique(self) -> bool:
    method get_class_id (line 498) | def get_class_id(self) -> int:
    method get_garrison_mode (line 504) | def get_garrison_mode(self, civ_id: int = -1) -> GenieGarrisonMode:
    method get_head_unit_id (line 543) | def get_head_unit_id(self) -> int:
    method get_head_unit (line 550) | def get_head_unit(self) -> GenieUnitObject:
    method get_unit_position (line 556) | def get_unit_position(self, unit_id: int) -> int:
    method get_train_location_id (line 562) | def get_train_location_id(self) -> typing.Union[int, None]:
    method __repr__ (line 573) | def __repr__(self):
  class GenieUnitLineGroup (line 577) | class GenieUnitLineGroup(GenieGameEntityGroup):
    method contains_unit (line 588) | def contains_unit(self, unit_id: int) -> bool:
    method get_civ_id (line 594) | def get_civ_id(self) -> typing.Union[int, None]:
    method get_enabling_research_id (line 610) | def get_enabling_research_id(self) -> int:
    method __repr__ (line 631) | def __repr__(self):
  class GenieBuildingLineGroup (line 635) | class GenieBuildingLineGroup(GenieGameEntityGroup):
    method __init__ (line 654) | def __init__(
    method add_gatherer_id (line 667) | def add_gatherer_id(self, unit_id: int) -> None:
    method add_trading_line (line 675) | def add_trading_line(self, unit_line: GenieGameEntityGroup) -> None:
    method contains_unit (line 683) | def contains_unit(self, building_id: int) -> bool:
    method has_foundation (line 689) | def has_foundation(self) -> bool:
    method is_dropsite (line 696) | def is_dropsite(self) -> bool:
    method is_repairable (line 702) | def is_repairable(self) -> bool:
    method is_trade_post (line 705) | def is_trade_post(self) -> bool:
    method get_gatherer_ids (line 711) | def get_gatherer_ids(self) -> set[int]:
    method get_enabling_research_id (line 717) | def get_enabling_research_id(self) -> int:
    method __repr__ (line 733) | def __repr__(self):
  class GenieStackBuildingGroup (line 737) | class GenieStackBuildingGroup(GenieBuildingLineGroup):
    method __init__ (line 750) | def __init__(
    method is_creatable (line 770) | def is_creatable(self, civ_id: int = -1) -> bool:
    method is_gate (line 785) | def is_gate(self) -> bool:
    method get_head_unit (line 794) | def get_head_unit(self) -> GenieUnitObject:
    method get_stack_unit (line 800) | def get_stack_unit(self) -> GenieUnitObject:
    method get_head_unit_id (line 806) | def get_head_unit_id(self) -> int:
    method get_stack_unit_id (line 812) | def get_stack_unit_id(self) -> int:
    method get_train_location_id (line 818) | def get_train_location_id(self) -> int:
    method __repr__ (line 830) | def __repr__(self):
  class GenieUnitTransformGroup (line 834) | class GenieUnitTransformGroup(GenieUnitLineGroup):
    method __init__ (line 844) | def __init__(
    method is_projectile_shooter (line 867) | def is_projectile_shooter(self, civ_id: int = -1) -> int:
    method get_head_unit_id (line 883) | def get_head_unit_id(self) -> int:
    method get_head_unit (line 889) | def get_head_unit(self) -> GenieUnitObject:
    method get_transform_unit_id (line 895) | def get_transform_unit_id(self) -> int:
    method get_transform_unit (line 901) | def get_transform_unit(self) -> GenieUnitObject:
    method __repr__ (line 907) | def __repr__(self):
  class GenieMonkGroup (line 911) | class GenieMonkGroup(GenieUnitLineGroup):
    method __init__ (line 923) | def __init__(
    method is_garrison (line 946) | def is_garrison(self, civ_id: int = -1) -> bool:
    method get_garrison_mode (line 949) | def get_garrison_mode(self, civ_id=-1) -> GenieGarrisonMode:
    method get_switch_unit (line 952) | def get_switch_unit(self) -> GenieUnitObject:
    method __repr__ (line 958) | def __repr__(self):
  class GenieAmbientGroup (line 962) | class GenieAmbientGroup(GenieGameEntityGroup):
    method contains_unit (line 971) | def contains_unit(self, ambient_id: int) -> bool:
    method is_creatable (line 977) | def is_creatable(self, civ_id: int = -1) -> bool:
    method is_gatherer (line 980) | def is_gatherer(self, civ_id: int = -1) -> bool:
    method is_melee (line 983) | def is_melee(self, civ_id: int = -1) -> bool:
    method is_ranged (line 986) | def is_ranged(self, civ_id: int = -1) -> bool:
    method is_projectile_shooter (line 989) | def is_projectile_shooter(self, civ_id: int = -1) -> bool:
    method is_unique (line 992) | def is_unique(self) -> bool:
    method __repr__ (line 995) | def __repr__(self):
  class GenieVariantGroup (line 999) | class GenieVariantGroup(GenieGameEntityGroup):
    method contains_unit (line 1007) | def contains_unit(self, object_id: int) -> bool:
    method is_creatable (line 1013) | def is_creatable(self, civ_id: int = -1) -> bool:
    method is_gatherer (line 1016) | def is_gatherer(self, civ_id: int = -1) -> bool:
    method is_melee (line 1019) | def is_melee(self, civ_id: int = -1) -> bool:
    method is_ranged (line 1022) | def is_ranged(self, civ_id: int = -1) -> bool:
    method is_unique (line 1025) | def is_unique(self) -> bool:
    method __repr__ (line 1028) | def __repr__(self):
  class GenieUnitTaskGroup (line 1032) | class GenieUnitTaskGroup(GenieUnitLineGroup):
    method __init__ (line 1050) | def __init__(
    method add_unit (line 1070) | def add_unit(
    method is_creatable (line 1084) | def is_creatable(self, civ_id: int = -1) -> bool:
    method get_train_location_id (line 1098) | def get_train_location_id(self) -> int:
    method __repr__ (line 1111) | def __repr__(self):
  class GenieVillagerGroup (line 1115) | class GenieVillagerGroup(GenieUnitLineGroup):
    method __init__ (line 1133) | def __init__(
    method contains_entity (line 1163) | def contains_entity(self, unit_id: int) -> bool:
    method has_command (line 1170) | def has_command(self, command_id: int, civ_id: int = -1) -> bool:
    method is_creatable (line 1183) | def is_creatable(self, civ_id: int = -1) -> bool:
    method is_garrison (line 1195) | def is_garrison(self, civ_id: int = -1) -> bool:
    method is_gatherer (line 1198) | def is_gatherer(self, civ_id: int = -1) -> bool:
    method is_hunter (line 1202) | def is_hunter(cls) -> bool:
    method is_unique (line 1208) | def is_unique(self) -> bool:
    method is_projectile_shooter (line 1211) | def is_projectile_shooter(self, civ_id: int = -1) -> bool:
    method get_garrison_mode (line 1214) | def get_garrison_mode(self, civ_id: int = -1) -> bool:
    method get_head_unit_id (line 1217) | def get_head_unit_id(self) -> int:
    method get_head_unit (line 1223) | def get_head_unit(self) -> GenieUnitObject:
    method get_units_with_command (line 1229) | def get_units_with_command(self, command_id: int) -> GenieUnitObject:
    method get_train_location_id (line 1247) | def get_train_location_id(self) -> int:
    method __repr__ (line 1258) | def __repr__(self):
  class GenieGarrisonMode (line 1262) | class GenieGarrisonMode(Enum):

FILE: openage/convert/entity_object/conversion/combined_sound.py
  class CombinedSound (line 17) | class CombinedSound:
    method __init__ (line 24) | def __init__(
    method add_reference (line 59) | def add_reference(self, referer: ConverterObject) -> None:
    method get_filename (line 65) | def get_filename(self) -> str:
    method get_file_id (line 71) | def get_file_id(self) -> int:
    method get_id (line 77) | def get_id(self) -> int:
    method get_relative_file_location (line 83) | def get_relative_file_location(self) -> str:
    method resolve_sound_location (line 96) | def resolve_sound_location(self) -> str:
    method remove_reference (line 108) | def remove_reference(self, referer: ConverterObject) -> None:
    method __repr__ (line 114) | def __repr__(self):

FILE: openage/convert/entity_object/conversion/combined_sprite.py
  class CombinedSprite (line 18) | class CombinedSprite:
    method __init__ (line 27) | def __init__(
    method add_reference (line 58) | def add_reference(self, referer: ConverterObject) -> None:
    method get_filename (line 64) | def get_filename(self) -> str:
    method get_graphics (line 70) | def get_graphics(self) -> list[GenieGraphic]:
    method get_id (line 85) | def get_id(self) -> int:
    method get_relative_sprite_location (line 91) | def get_relative_sprite_location(self) -> str:
    method remove_reference (line 104) | def remove_reference(self, referer: ConverterObject) -> None:
    method resolve_graphics_location (line 110) | def resolve_graphics_location(self) -> str:
    method resolve_sprite_location (line 126) | def resolve_sprite_location(self) -> str:
    method __repr__ (line 138) | def __repr__(self):

FILE: openage/convert/entity_object/conversion/combined_terrain.py
  class CombinedTerrain (line 18) | class CombinedTerrain:
    method __init__ (line 27) | def __init__(
    method add_reference (line 57) | def add_reference(self, referer: ConverterObject) -> None:
    method get_filename (line 63) | def get_filename(self) -> str:
    method get_terrain (line 69) | def get_terrain(self) -> GenieTerrainObject:
    method get_id (line 75) | def get_id(self) -> int:
    method get_relative_terrain_location (line 81) | def get_relative_terrain_location(self) -> str:
    method remove_reference (line 91) | def remove_reference(self, referer: ConverterObject) -> None:
    method resolve_graphics_location (line 97) | def resolve_graphics_location(self) -> str:
    method resolve_terrain_location (line 104) | def resolve_terrain_location(self) -> str:
    method __repr__ (line 113) | def __repr__(self):

FILE: openage/convert/entity_object/conversion/converter_object.py
  class ConverterObject (line 25) | class ConverterObject:
    method __init__ (line 32) | def __init__(
    method get_id (line 59) | def get_id(self) -> typing.Union[str, int]:
    method add_member (line 65) | def add_member(self, member: ValueMember) -> None:
    method add_members (line 71) | def add_members(self, members: dict[str, ValueMember]) -> None:
    method get_member (line 77) | def get_member(self, member_id: str) -> ValueMember:
    method has_member (line 87) | def has_member(self, member_id: str) -> bool:
    method remove_member (line 93) | def remove_member(self, member_id: str) -> None:
    method short_diff (line 99) | def short_diff(self, other: ConverterObject) -> ConverterObject:
    method diff (line 119) | def diff(self, other: ConverterObject) -> ConverterObject:
    method __getitem__ (line 133) | def __getitem__(self, key):
    method __repr__ (line 139) | def __repr__(self):
  class ConverterObjectGroup (line 144) | class ConverterObjectGroup:
    method __init__ (line 153) | def __init__(
    method get_id (line 177) | def get_id(self) -> typing.Union[str, int]:
    method add_raw_api_object (line 183) | def add_raw_api_object(self, subobject: RawAPIObject) -> None:
    method add_raw_api_objects (line 190) | def add_raw_api_objects(self, subobjects: list[RawAPIObject]) -> None:
    method add_raw_member_push (line 197) | def add_raw_member_push(self, push_object: RawMemberPush) -> None:
    method create_nyan_objects (line 203) | def create_nyan_objects(self) -> None:
    method create_nyan_members (line 217) | def create_nyan_members(self) -> None:
    method check_readiness (line 224) | def check_readiness(self) -> None:
    method execute_raw_member_pushs (line 239) | def execute_raw_member_pushs(self) -> None:
    method get_raw_api_object (line 250) | def get_raw_api_object(self, obj_id: str) -> RawAPIObject:
    method get_raw_api_objects (line 261) | def get_raw_api_objects(self) -> dict[str, RawAPIObject]:
    method has_raw_api_object (line 267) | def has_raw_api_object(self, obj_id: typing.Union[str, int]) -> bool:
    method remove_raw_api_object (line 273) | def remove_raw_api_object(self, obj_id: typing.Union[str, int]) -> None:
    method _create_raw_api_object_dict (line 279) | def _create_raw_api_object_dict(self, subobject_list: list[RawAPIObjec...
    method __repr__ (line 286) | def __repr__(self):
  class RawAPIObject (line 290) | class RawAPIObject:
    method __init__ (line 303) | def __init__(
    method add_raw_member (line 338) | def add_raw_member(
    method add_raw_patch_member (line 356) | def add_raw_patch_member(
    method add_raw_parent (line 377) | def add_raw_parent(self, parent_id: str) -> None:
    method add_raw_patch_parent (line 386) | def add_raw_patch_parent(self, parent_id: str) -> None:
    method extend_raw_member (line 395) | def extend_raw_member(
    method create_nyan_object (line 424) | def create_nyan_object(self) -> None:
    method create_nyan_members (line 438) | def create_nyan_members(self) -> None:
    method link_patch_target (line 468) | def link_patch_target(self) -> None:
    method get_filename (line 483) | def get_filename(self) -> str:
    method get_file_location (line 489) | def get_file_location(self) -> str:
    method get_id (line 512) | def get_id(self) -> typing.Union[str, int]:
    method get_location (line 518) | def get_location(self) -> typing.Union[str, ForwardRef]:
    method get_nyan_object (line 525) | def get_nyan_object(self) -> NyanObject:
    method is_ready (line 534) | def is_ready(self) -> bool:
    method is_patch (line 540) | def is_patch(self) -> bool:
    method set_filename (line 546) | def set_filename(self, filename: str, suffix: str = "nyan") -> None:
    method set_location (line 557) | def set_location(self, location: typing.Union[str, ForwardRef]) -> None:
    method set_patch_target (line 568) | def set_patch_target(self, target: typing.Union[ForwardRef, NyanObject]):
    method _resolve_raw_value (line 579) | def _resolve_raw_value(value) -> typing.Union[NyanObject, str, float]:
    method _resolve_raw_values (line 610) | def _resolve_raw_values(self, values):
    method __repr__ (line 638) | def __repr__(self):
  class RawMemberPush (line 642) | class RawMemberPush:
    method __init__ (line 652) | def __init__(
    method get_object_target (line 676) | def get_object_target(self) -> ForwardRef:
    method get_member_name (line 682) | def get_member_name(self) -> str:
    method get_member_origin (line 688) | def get_member_origin(self) -> str:
    method get_push_value (line 694) | def get_push_value(self) -> list:
  class ConverterObjectContainer (line 701) | class ConverterObjectContainer:
    method __repr__ (line 709) | def __repr__(self):

FILE: openage/convert/entity_object/conversion/modpack.py
  class Modpack (line 16) | class Modpack:
    method __init__ (line 21) | def __init__(self, name: str):
    method add_data_export (line 36) | def add_data_export(self, export_file: DataDefinition) -> None:
    method add_media_export (line 46) | def add_media_export(self, export_request: MediaExportRequest) -> None:
    method add_metadata_export (line 60) | def add_metadata_export(self, export_file: MetadataExport) -> None:
    method get_info (line 70) | def get_info(self) -> ModpackInfo:
    method get_data_files (line 76) | def get_data_files(self) -> list[DataDefinition]:
    method get_media_files (line 82) | def get_media_files(self) -> list[MediaExportRequest]:
    method get_metadata_files (line 88) | def get_metadata_files(self) -> list[MetadataExport]:

FILE: openage/convert/entity_object/conversion/ror/genie_sound.py
  class RoRSound (line 14) | class RoRSound(GenieSound):
    method get_sounds (line 20) | def get_sounds(self, civ_id: int = -1) -> list[int]:
    method __repr__ (line 33) | def __repr__(self):

FILE: openage/convert/entity_object/conversion/ror/genie_tech.py
  class RoRStatUpgrade (line 18) | class RoRStatUpgrade(StatUpgrade):
    method is_unique (line 23) | def is_unique(self) -> bool:
    method __repr__ (line 26) | def __repr__(self):
  class RoRAgeUpgrade (line 30) | class RoRAgeUpgrade(AgeUpgrade):
    method is_unique (line 35) | def is_unique(self) -> bool:
    method __repr__ (line 38) | def __repr__(self):
  class RoRUnitLineUpgrade (line 42) | class RoRUnitLineUpgrade(UnitLineUpgrade):
    method get_upgraded_line (line 47) | def get_upgraded_line(self) -> RoRUnitLineGroup:
    method is_unique (line 50) | def is_unique(self) -> bool:
    method __repr__ (line 53) | def __repr__(self):
  class RoRBuildingLineUpgrade (line 57) | class RoRBuildingLineUpgrade(BuildingLineUpgrade):
    method is_unique (line 62) | def is_unique(self) -> bool:
    method __repr__ (line 65) | def __repr__(self):
  class RoRUnitUnlock (line 69) | class RoRUnitUnlock(UnitUnlock):
    method is_unique (line 74) | def is_unique(self) -> bool:
    method get_unlocked_line (line 77) | def get_unlocked_line(self) -> RoRUnitLineGroup:
    method __repr__ (line 83) | def __repr__(self):
  class RoRBuildingUnlock (line 87) | class RoRBuildingUnlock(BuildingUnlock):
    method is_unique (line 92) | def is_unique(self) -> bool:
    method __repr__ (line 95) | def __repr__(self):

FILE: openage/convert/entity_object/conversion/ror/genie_unit.py
  class RoRUnitLineGroup (line 20) | class RoRUnitLineGroup(GenieUnitLineGroup):
    method __init__ (line 31) | def __init__(
    method is_garrison (line 51) | def is_garrison(self, civ_id: int = -1) -> bool:
    method is_passable (line 59) | def is_passable(self, civ_id: int = -1) -> bool:
    method get_garrison_mode (line 68) | def get_garrison_mode(self, civ_id: int = -1) -> typing.Union[GenieGar...
    method get_enabling_research_id (line 80) | def get_enabling_research_id(self) -> int:
    method __repr__ (line 83) | def __repr__(self):
  class RoRBuildingLineGroup (line 87) | class RoRBuildingLineGroup(GenieBuildingLineGroup):
    method __init__ (line 98) | def __init__(
    method is_garrison (line 118) | def is_garrison(self, civ_id: int = -1) -> bool:
    method is_passable (line 121) | def is_passable(self, civ_id: int = -1) -> bool:
    method get_garrison_mode (line 130) | def get_garrison_mode(self, civ_id: int = -1) -> None:
    method get_enabling_research_id (line 133) | def get_enabling_research_id(self) -> int:
    method __repr__ (line 136) | def __repr__(self):
  class RoRAmbientGroup (line 140) | class RoRAmbientGroup(GenieAmbientGroup):
    method is_garrison (line 149) | def is_garrison(self, civ_id: int = -1) -> bool:
    method is_passable (line 152) | def is_passable(self, civ_id: int = -1) -> bool:
    method get_garrison_mode (line 161) | def get_garrison_mode(self, civ_id: int = -1) -> None:
    method __repr__ (line 164) | def __repr__(self):
  class RoRVariantGroup (line 168) | class RoRVariantGroup(GenieVariantGroup):
    method is_garrison (line 176) | def is_garrison(self, civ_id: int = -1) -> bool:
    method is_passable (line 179) | def is_passable(self, civ_id: int = -1) -> bool:
    method get_garrison_mode (line 188) | def get_garrison_mode(self, civ_id: int = -1) -> None:
    method __repr__ (line 191) | def __repr__(self):
  class RoRUnitTaskGroup (line 195) | class RoRUnitTaskGroup(GenieUnitTaskGroup):
    method __init__ (line 208) | def __init__(
    method is_garrison (line 230) | def is_garrison(self, civ_id: int = -1) -> bool:
    method is_passable (line 238) | def is_passable(self, civ_id: int = -1) -> bool:
    method get_garrison_mode (line 247) | def get_garrison_mode(self, civ_id: int = -1) -> typing.Union[GenieGar...
    method get_enabling_research_id (line 259) | def get_enabling_research_id(self) -> int:
    method __repr__ (line 262) | def __repr__(self):
  class RoRVillagerGroup (line 266) | class RoRVillagerGroup(GenieVillagerGroup):
    method is_passable (line 272) | def is_passable(self, civ_id: int = -1) -> bool:
    method get_enabling_research_id (line 275) | def get_enabling_research_id(self) -> int:
    method __repr__ (line 278) | def __repr__(self):

FILE: openage/convert/entity_object/conversion/stringresource.py
  class StringResource (line 16) | class StringResource(GenieStructure):
    method __init__ (line 18) | def __init__(self):
    method fill_from (line 22) | def fill_from(self, stringtable: dict[str, dict[str, str]]) -> None:
    method get_tables (line 29) | def get_tables(self) -> dict[str, dict[str, str]]:
    method get_data_format_members (line 36) | def get_data_format_members(cls, game_version: GameVersion) -> tuple:

FILE: openage/convert/entity_object/conversion/swgbcc/genie_tech.py
  class SWGBUnitLineUpgrade (line 17) | class SWGBUnitLineUpgrade(UnitLineUpgrade):
    method __init__ (line 24) | def __init__(
    method add_civ_upgrade (line 47) | def add_civ_upgrade(self, other_unlock: SWGBUnitUnlock) -> None:
    method is_unique (line 55) | def is_unique(self) -> bool:
  class SWGBUnitUnlock (line 64) | class SWGBUnitUnlock(UnitUnlock):
    method __init__ (line 71) | def __init__(
    method add_civ_unlock (line 92) | def add_civ_unlock(self, other_unlock: SWGBUnitUnlock) -> None:
    method is_unique (line 100) | def is_unique(self) -> bool:

FILE: openage/convert/entity_object/conversion/swgbcc/genie_unit.py
  class SWGBUnitLineGroup (line 18) | class SWGBUnitLineGroup(GenieUnitLineGroup):
    method __init__ (line 32) | def __init__(
    method add_civ_line (line 50) | def add_civ_line(self, other_line: SWGBUnitLineGroup) -> None:
    method get_civ_id (line 58) | def get_civ_id(self) -> int:
    method is_civ_unique (line 65) | def is_civ_unique(self) -> bool:
    method is_unique (line 73) | def is_unique(self) -> bool:
    method __repr__ (line 84) | def __repr__(self):
  class SWGBStackBuildingGroup (line 88) | class SWGBStackBuildingGroup(GenieStackBuildingGroup):
    method get_enabling_research_id (line 96) | def get_enabling_research_id(self) -> int:
    method __repr__ (line 107) | def __repr__(self):
  class SWGBUnitTransformGroup (line 111) | class SWGBUnitTransformGroup(GenieUnitTransformGroup):
    method __init__ (line 124) | def __init__(
    method add_civ_line (line 144) | def add_civ_line(self, other_line: SWGBUnitLineGroup) -> None:
    method get_civ_id (line 152) | def get_civ_id(self) -> int:
    method is_civ_unique (line 159) | def is_civ_unique(self) -> bool:
    method is_unique (line 167) | def is_unique(self) -> bool:
    method get_enabling_research_id (line 176) | def get_enabling_research_id(self) -> int:
    method __repr__ (line 185) | def __repr__(self):
  class SWGBMonkGroup (line 189) | class SWGBMonkGroup(GenieMonkGroup):
    method __init__ (line 200) | def __init__(
    method add_civ_line (line 223) | def add_civ_line(self, other_line: SWGBMonkGroup) -> None:
    method get_civ_id (line 231) | def get_civ_id(self) -> int:
    method is_civ_unique (line 238) | def is_civ_unique(self) -> bool:
    method is_unique (line 246) | def is_unique(self) -> bool:
    method __repr__ (line 255) | def __repr__(self):

FILE: openage/convert/entity_object/export/data_definition.py
  class DataDefinition (line 11) | class DataDefinition:
    method __init__ (line 17) | def __init__(self, targetdir: str, filename: str):
    method dump (line 29) | def dump(self) -> typing.NoReturn:
    method set_filename (line 35) | def set_filename(self, filename: str) -> None:
    method set_targetdir (line 47) | def set_targetdir(self, targetdir: str) -> None:
    method __repr__ (line 59) | def __repr__(self):

FILE: openage/convert/entity_object/export/formats/blmask_metadata.py
  class BlendmaskMetadata (line 16) | class BlendmaskMetadata(DataDefinition):
    method __init__ (line 22) | def __init__(self, targetdir: str, filename: str):
    method add_image (line 29) | def add_image(self, img_id: int, filename: str) -> None:
    method add_mask (line 43) | def add_mask(
    method set_scalefactor (line 77) | def set_scalefactor(self, factor: typing.Union[int, float]) -> None:
    method dump (line 86) | def dump(self) -> str:
    method __repr__ (line 110) | def __repr__(self):

FILE: openage/convert/entity_object/export/formats/bltable_metadata.py
  class BlendtableMetadata (line 14) | class BlendtableMetadata(DataDefinition):
    method __init__ (lin
Condensed preview — 1669 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (8,032K chars).
[
  {
    "path": ".clang-format",
    "chars": 3806,
    "preview": "---\n# SFT codestyle\n# Tab indent + space alignment\n# see documentation in doc/code_style/ for details and explainations"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATES/pull_request_template.md",
    "chars": 495,
    "preview": "### Merge Checklist\n\n<!-- Complete all tasks below to make sure that we can merge your pull request. -->\n<!-- If you are"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATES/release_template.md",
    "chars": 154,
    "preview": "### Checklist\n\n- [ ] Changelog\n    - [ ] Release date\n    - [ ] Version number in title\n    - [ ] Full commit log\n- [ ] "
  },
  {
    "path": ".github/workflows/macosx-ci.yml",
    "chars": 2568,
    "preview": "name: macOS-CI\non: [push, pull_request]\n\njobs:\n  # https://docs.github.com/en/actions/reference/software-installed-on-gi"
  },
  {
    "path": ".github/workflows/ubuntu-24.04.yml",
    "chars": 2368,
    "preview": "name: Ubuntu 24.04 CI\n\non: [push, workflow_dispatch]\n\njobs:\n  build-devenv:\n    runs-on: ubuntu-24.04\n    steps:\n    - u"
  },
  {
    "path": ".github/workflows/windows-server-2019.yml",
    "chars": 4055,
    "preview": "name: Windows Server 2019 CI\n\non: [push, workflow_dispatch]\n\njobs:\n  build-x64:\n    runs-on: windows-2019\n    steps:\n   "
  },
  {
    "path": ".github/workflows/windows-server-2022.yml",
    "chars": 4055,
    "preview": "name: Windows Server 2022 CI\n\non: [push, workflow_dispatch]\n\njobs:\n  build-x64:\n    runs-on: windows-2022\n    steps:\n   "
  },
  {
    "path": ".gitignore",
    "chars": 833,
    "preview": "# editor-specific files\n\\#*\n.#*\n*~\n.*.swp\n/CMakeLists.txt.user\n*.temp\n\n# ELF files\n*.o\n*.a\n*.so\n\n# python bytecode\n*.pyc"
  },
  {
    "path": ".mailmap",
    "chars": 1367,
    "preview": "Michael Enßlin <michael@ensslin.cc>\nJonas Jelten <jj@sft.lol> <jonas.jelten@gmail.com>\nJonas Jelten <jj@sft.lol> <jelten"
  },
  {
    "path": "CMakeLists.txt",
    "chars": 8063,
    "preview": "# Copyright 2013-2023 the openage authors. See copying.md for legal info.\n\n# >=3.16 finding numpy with the findpython3 m"
  },
  {
    "path": "Makefile",
    "chars": 5901,
    "preview": "# type 'make help' for a list/explaination of recipes.\n\nBUILDDIR = bin\n\nMAKEARGS += $(if $(VERBOSE),,--no-print-director"
  },
  {
    "path": "README.md",
    "chars": 11897,
    "preview": "[![openage](/assets/logo/banner.svg)](http://openage.dev)\n=========================================================\n\n**o"
  },
  {
    "path": "assets/.gitignore",
    "chars": 36,
    "preview": "# converted game assets\n/converted/\n"
  },
  {
    "path": "assets/CMakeLists.txt",
    "chars": 360,
    "preview": "# Copyright 2014-2017 the openage authors. See copying.md for legal info.\n\nadd_subdirectory(logo/)\nadd_subdirectory(shad"
  },
  {
    "path": "assets/logo/CMakeLists.txt",
    "chars": 142,
    "preview": "install(\n\tFILES \"crown.svg\"\n\tRENAME \"openage.svg\"\n\tDESTINATION \"share/pixmaps/\"\n)\n\ninstall(\n\tFILES \"banner.svg\"\n\tDESTINA"
  },
  {
    "path": "assets/qml/.gitignore",
    "chars": 7,
    "preview": "*.qmlc\n"
  },
  {
    "path": "assets/qml/Actions.qml",
    "chars": 1103,
    "preview": "// Copyright 2016-2017 the openage authors. See copying.md for legal info.\n\nimport QtQuick 2.4\nimport QtQuick.Controls 1"
  },
  {
    "path": "assets/qml/ActionsGrid.qml",
    "chars": 1183,
    "preview": "// Copyright 2016-2017 the openage authors. See copying.md for legal info.\n\nimport QtQuick 2.4\nimport QtQuick.Controls 1"
  },
  {
    "path": "assets/qml/BindsHelp.qml",
    "chars": 810,
    "preview": "// Copyright 2015-2017 the openage authors. See copying.md for legal info.\n\nimport QtQuick 2.4\nimport QtQuick.Controls 1"
  },
  {
    "path": "assets/qml/ButtonExtruded.qml",
    "chars": 201,
    "preview": "// Copyright 2015-2017 the openage authors. See copying.md for legal info.\n\nimport QtQuick 2.4\nimport QtQuick.Controls 1"
  },
  {
    "path": "assets/qml/ButtonExtrudedStyle.qml",
    "chars": 965,
    "preview": "// Copyright 2015-2017 the openage authors. See copying.md for legal info.\n\nimport QtQuick 2.4\nimport QtQuick.Controls 1"
  },
  {
    "path": "assets/qml/ButtonFlat.qml",
    "chars": 197,
    "preview": "// Copyright 2015-2017 the openage authors. See copying.md for legal info.\n\nimport QtQuick 2.4\nimport QtQuick.Controls 1"
  },
  {
    "path": "assets/qml/ButtonFlatStyle.qml",
    "chars": 1160,
    "preview": "// Copyright 2015-2017 the openage authors. See copying.md for legal info.\n\nimport QtQuick 2.4\nimport QtQuick.Controls 1"
  },
  {
    "path": "assets/qml/CheckBoxFlat.qml",
    "chars": 201,
    "preview": "// Copyright 2015-2017 the openage authors. See copying.md for legal info.\n\nimport QtQuick 2.4\nimport QtQuick.Controls 1"
  },
  {
    "path": "assets/qml/CheckBoxFlatStyle.qml",
    "chars": 774,
    "preview": "// Copyright 2015-2017 the openage authors. See copying.md for legal info.\n\nimport QtQuick 2.4\nimport QtQuick.Controls 1"
  },
  {
    "path": "assets/qml/CreateGameWhenReady.qml",
    "chars": 748,
    "preview": "// Copyright 2015-2017 the openage authors. See copying.md for legal info.\n\nimport QtQuick 2.4\n\nimport yay.sfttech.opena"
  },
  {
    "path": "assets/qml/GeneratorControl.qml",
    "chars": 1865,
    "preview": "// Copyright 2015-2017 the openage authors. See copying.md for legal info.\n\nimport QtQuick 2.4\nimport QtQuick.Controls 1"
  },
  {
    "path": "assets/qml/GeneratorParametersConfiguration.qml",
    "chars": 1051,
    "preview": "// Copyright 2015-2017 the openage authors. See copying.md for legal info.\n\nimport QtQuick 2.4\nimport QtQuick.Controls 1"
  },
  {
    "path": "assets/qml/IngameHud.qml",
    "chars": 8055,
    "preview": "// Copyright 2015-2017 the openage authors. See copying.md for legal info.\n\nimport QtQuick 2.4\nimport QtQuick.Controls 1"
  },
  {
    "path": "assets/qml/Paper.qml",
    "chars": 4685,
    "preview": "// Copyright 2015-2017 the openage authors. See copying.md for legal info.\n\nimport QtQuick 2.4\n\nItem {\n\tid: root\n\n\t/*\n\t "
  },
  {
    "path": "assets/qml/TextFieldFlat.qml",
    "chars": 203,
    "preview": "// Copyright 2015-2017 the openage authors. See copying.md for legal info.\n\nimport QtQuick 2.4\nimport QtQuick.Controls 1"
  },
  {
    "path": "assets/qml/TextFieldFlatStyle.qml",
    "chars": 305,
    "preview": "// Copyright 2015-2017 the openage authors. See copying.md for legal info.\n\nimport QtQuick 2.4\nimport QtQuick.Controls 1"
  },
  {
    "path": "assets/qml/TypePicker.qml",
    "chars": 3742,
    "preview": "// Copyright 2015-2017 the openage authors. See copying.md for legal info.\n\nimport QtQuick 2.4\nimport QtQuick.Controls 1"
  },
  {
    "path": "assets/qml/main.qml",
    "chars": 4627,
    "preview": "// Copyright 2015-2017 the openage authors. See copying.md for legal info.\n\nimport QtQuick 2.4\nimport QtQuick.Controls 1"
  },
  {
    "path": "assets/shaders/CMakeLists.txt",
    "chars": 93,
    "preview": "install(DIRECTORY \".\"\n\tDESTINATION \"${ASSET_DIR}/shaders\"\n\tFILES_MATCHING PATTERN \"*.glsl\"\n)\n"
  },
  {
    "path": "assets/shaders/alphamask.frag.glsl",
    "chars": 848,
    "preview": "// alpha masking shader\n//\n// applies an alpha mask texture to a base texture,\n// then draws the masked texture.\n\n// the"
  },
  {
    "path": "assets/shaders/alphamask.vert.glsl",
    "chars": 705,
    "preview": "// vertex shader for applying an alpha mask to a texture\n\n// modelview*projection matrix\nuniform mat4 mvp_matrix;\n\n// th"
  },
  {
    "path": "assets/shaders/equalsEpsilon.glsl",
    "chars": 478,
    "preview": "bool equalsEpsilon(vec4 left, vec4 right, float epsilon) {\n\treturn all(lessThanEqual(abs(left - right), vec4(epsilon)));"
  },
  {
    "path": "assets/shaders/final.frag.glsl",
    "chars": 125,
    "preview": "#version 330\n\nin vec2 tex_pos;\n\nout vec4 out_col;\n\nuniform sampler2D tex;\n\nvoid main() {\n\tout_col = texture(tex, tex_pos"
  },
  {
    "path": "assets/shaders/final.vert.glsl",
    "chars": 174,
    "preview": "#version 330\n\nlayout(location=0) in vec2 position;\nlayout(location=1) in vec2 uv;\n\nout vec2 tex_pos;\n\nvoid main() {\n\tgl_"
  },
  {
    "path": "assets/shaders/hud_drag_select.frag.glsl",
    "chars": 140,
    "preview": "#version 330\n\n// Color of the drag rectangle\nuniform vec4 in_col;\n\nlayout(location=0) out vec4 out_col;\n\nvoid main() {\n\t"
  },
  {
    "path": "assets/shaders/hud_drag_select.vert.glsl",
    "chars": 109,
    "preview": "#version 330\n\nlayout(location=0) in vec2 position;\n\nvoid main() {\n\tgl_Position = vec4(position, 0.0, 1.0);\n}\n"
  },
  {
    "path": "assets/shaders/identity.vert.glsl",
    "chars": 401,
    "preview": "#version 120\n\n// no-transformation texture mapping vertex shader\n\n// the position of this vertex\nattribute vec4 vertex_p"
  },
  {
    "path": "assets/shaders/maptexture.frag.glsl",
    "chars": 342,
    "preview": "#version 120\n// total basic standard texture drawing fragment shader\n\n// the texture data\nuniform sampler2D texture;\n\n//"
  },
  {
    "path": "assets/shaders/maptexture.vert.glsl",
    "chars": 562,
    "preview": "//total basic standard texture mapping vertex shader\n\n//modelview*projection matrix\nuniform mat4 mvp_matrix;\n\n//the posi"
  },
  {
    "path": "assets/shaders/skybox.frag.glsl",
    "chars": 109,
    "preview": "#version 330\n\nuniform vec4 in_col;\n\nlayout(location=0) out vec4 out_col;\n\nvoid main() {\n\tout_col = in_col;\n}\n"
  },
  {
    "path": "assets/shaders/skybox.vert.glsl",
    "chars": 109,
    "preview": "#version 330\n\nlayout(location=0) in vec2 position;\n\nvoid main() {\n\tgl_Position = vec4(position, 0.0, 1.0);\n}\n"
  },
  {
    "path": "assets/shaders/teamcolors.frag.glsl",
    "chars": 1714,
    "preview": "//team color replacement shader\n//\n//looks for an alpha value specified by 'alpha_marker'\n//and then replaces this pixel"
  },
  {
    "path": "assets/shaders/terrain.frag.glsl",
    "chars": 172,
    "preview": "#version 330\n\nin vec2 tex_pos;\n\nlayout(location=0) out vec4 out_col;\n\nuniform sampler2D tex;\n\nvoid main()\n{\n    vec4 tex"
  },
  {
    "path": "assets/shaders/terrain.vert.glsl",
    "chars": 641,
    "preview": "#version 330\n\nlayout (location = 0) in vec3 position;\nlayout (location = 1) in vec2 uv;\n\nout vec2 tex_pos;\n\nuniform mat4"
  },
  {
    "path": "assets/shaders/texturefont.frag.glsl",
    "chars": 294,
    "preview": "varying vec2 tex_position;\nuniform sampler2D texture;\nuniform vec4 color;\n\nvoid main() {\n\t// Glyph's image data is store"
  },
  {
    "path": "assets/shaders/texturefont.vert.glsl",
    "chars": 204,
    "preview": "attribute vec4 vertex_position;\nattribute vec2 tex_coordinates;\nvarying vec2 tex_position;\n\nvoid main() {\n\tgl_Position ="
  },
  {
    "path": "assets/shaders/world2d.frag.glsl",
    "chars": 761,
    "preview": "#version 330\n\nin vec2 vert_uv;\n\nlayout(location=0) out vec4 col;\nlayout(location=1) out uint id;\n\nuniform sampler2D tex;"
  },
  {
    "path": "assets/shaders/world2d.vert.glsl",
    "chars": 3871,
    "preview": "#version 330\n\nlayout(location=0) in vec2 v_position;\nlayout(location=1) in vec2 uv;\n\nout vec2 vert_uv;\n\n// camera parame"
  },
  {
    "path": "assets/shaders/world3d.vert.glsl",
    "chars": 278,
    "preview": "#version 330\n\nlayout(location=0) in vec2 position;\nlayout(location=1) in vec2 uv;\n\nout vec2 vert_uv;\n\nuniform mat4 model"
  },
  {
    "path": "assets/test/CMakeLists.txt",
    "chars": 177,
    "preview": "# Copyright 2023-2023 the openage authors. See copying.md for legal info.\n\nadd_subdirectory(nyan/)\nadd_subdirectory(qml/"
  },
  {
    "path": "assets/test/nyan/CMakeLists.txt",
    "chars": 95,
    "preview": "install(DIRECTORY \".\"\n\tDESTINATION \"${ASSET_DIR}/test/nyan\"\n\tFILES_MATCHING PATTERN \"*.nyan\"\n)\n"
  },
  {
    "path": "assets/test/nyan/pong.nyan",
    "chars": 442,
    "preview": "!version 1\n\nPongGame():\n    ball : Ball\n    player1 : Player\n    player2 : Player\n\nBall():\n    Color():\n        r : int "
  },
  {
    "path": "assets/test/qml/CMakeLists.txt",
    "chars": 93,
    "preview": "install(DIRECTORY \".\"\n\tDESTINATION \"${ASSET_DIR}/test/qml\"\n\tFILES_MATCHING PATTERN \"*.qml\"\n)\n"
  },
  {
    "path": "assets/test/qml/main.qml",
    "chars": 485,
    "preview": "// Copyright 2015-2017 the openage authors. See copying.md for legal info.\n\nimport QtQuick 2.4\nimport yay.sfttech.livere"
  },
  {
    "path": "assets/test/shaders/CMakeLists.txt",
    "chars": 98,
    "preview": "install(DIRECTORY \".\"\n\tDESTINATION \"${ASSET_DIR}/test/shaders\"\n\tFILES_MATCHING PATTERN \"*.glsl\"\n)\n"
  },
  {
    "path": "assets/test/shaders/demo_0_display.frag.glsl",
    "chars": 81,
    "preview": "#version 330\n\nout vec4 col;\n\nvoid main() {\n    col = vec4(1.0, 0.4, 0.0, 0.8);\n}\n"
  },
  {
    "path": "assets/test/shaders/demo_0_display.vert.glsl",
    "chars": 109,
    "preview": "#version 330\n\nlayout(location=0) in vec2 position;\n\nvoid main() {\n\tgl_Position = vec4(position, 0.0, 1.0);\n}\n"
  },
  {
    "path": "assets/test/shaders/demo_1_display.frag.glsl",
    "chars": 130,
    "preview": "#version 330\n\nuniform sampler2D color_texture;\n\nin vec2 v_uv;\nout vec4 col;\n\nvoid main() {\n\tcol = texture(color_texture,"
  },
  {
    "path": "assets/test/shaders/demo_1_display.vert.glsl",
    "chars": 168,
    "preview": "#version 330\n\nlayout(location=0) in vec2 position;\nlayout(location=1) in vec2 uv;\nout vec2 v_uv;\n\nvoid main() {\n\tgl_Posi"
  },
  {
    "path": "assets/test/shaders/demo_1_obj.frag.glsl",
    "chars": 254,
    "preview": "#version 330\n\nin vec2 v_uv;\nuniform sampler2D tex;\nuniform uint u_id;\n\nlayout(location=0) out vec4 col;\nlayout(location="
  },
  {
    "path": "assets/test/shaders/demo_1_obj.vert.glsl",
    "chars": 235,
    "preview": "#version 330\n\nlayout(location=0) in vec2 position;\nlayout(location=1) in vec2 uv;\nuniform mat4 mv;\nuniform mat4 proj;\nou"
  },
  {
    "path": "assets/test/shaders/demo_2_display.frag.glsl",
    "chars": 130,
    "preview": "#version 330\n\nuniform sampler2D color_texture;\n\nin vec2 v_uv;\nout vec4 col;\n\nvoid main() {\n\tcol = texture(color_texture,"
  },
  {
    "path": "assets/test/shaders/demo_2_display.vert.glsl",
    "chars": 167,
    "preview": "#version 330\n\nlayout(location=0) in vec2 position;\nlayout(location=1) in vec2 uv;\nout vec2 v_uv;\n\nvoid main() {\n\tgl_Posi"
  },
  {
    "path": "assets/test/shaders/demo_2_obj.frag.glsl",
    "chars": 511,
    "preview": "#version 330\n\nin vec2 v_uv;\nuniform sampler2D tex;\nuniform uint u_id;\n\nlayout(location=0) out vec4 col;\nlayout(location="
  },
  {
    "path": "assets/test/shaders/demo_2_obj.vert.glsl",
    "chars": 415,
    "preview": "#version 330\n\nlayout(location=0) in vec2 position;\nlayout(location=1) in vec2 uv;\n\nuniform mat4 mv;\nuniform mat4 proj;\nu"
  },
  {
    "path": "assets/test/shaders/demo_4_display.frag.glsl",
    "chars": 130,
    "preview": "#version 330\n\nuniform sampler2D color_texture;\n\nin vec2 v_uv;\nout vec4 col;\n\nvoid main() {\n\tcol = texture(color_texture,"
  },
  {
    "path": "assets/test/shaders/demo_4_display.vert.glsl",
    "chars": 167,
    "preview": "#version 330\n\nlayout(location=0) in vec2 position;\nlayout(location=1) in vec2 uv;\nout vec2 v_uv;\n\nvoid main() {\n\tgl_Posi"
  },
  {
    "path": "assets/test/shaders/demo_4_obj.frag.glsl",
    "chars": 511,
    "preview": "#version 330\n\nin vec2 v_uv;\nuniform sampler2D tex;\nuniform uint u_id;\n\nlayout(location=0) out vec4 col;\nlayout(location="
  },
  {
    "path": "assets/test/shaders/demo_4_obj.vert.glsl",
    "chars": 415,
    "preview": "#version 330\n\nlayout(location=0) in vec2 position;\nlayout(location=1) in vec2 uv;\n\nuniform mat4 mv;\nuniform mat4 proj;\nu"
  },
  {
    "path": "assets/test/shaders/demo_5_obj.frag.glsl",
    "chars": 172,
    "preview": "#version 330\n\nin vec2 tex_pos;\n\nlayout(location=0) out vec4 out_col;\n\nuniform sampler2D tex;\n\nvoid main()\n{\n    vec4 tex"
  },
  {
    "path": "assets/test/shaders/demo_5_obj.vert.glsl",
    "chars": 305,
    "preview": "#version 330\n\nlayout (location = 0) in vec3 position;\nlayout (location = 1) in vec2 uv;\n\nout vec2 tex_pos;\n\nuniform mat4"
  },
  {
    "path": "assets/test/shaders/demo_6_2d.frag.glsl",
    "chars": 661,
    "preview": "#version 330\n\nin vec2 vert_uv;\n\nlayout(location=0) out vec4 col;\n\nuniform sampler2D tex;\n\n// position (top left corner) "
  },
  {
    "path": "assets/test/shaders/demo_6_2d.vert.glsl",
    "chars": 2961,
    "preview": "#version 330\n\nlayout(location=0) in vec2 v_position;\nlayout(location=1) in vec2 uv;\n\nout vec2 vert_uv;\n\n// camera parame"
  },
  {
    "path": "assets/test/shaders/demo_6_2d_frame.frag.glsl",
    "chars": 89,
    "preview": "#version 330\n\nout vec4 outcol;\n\nuniform vec4 incol;\n\nvoid main() {\n    outcol = incol;\n}\n"
  },
  {
    "path": "assets/test/shaders/demo_6_2d_frame.vert.glsl",
    "chars": 2082,
    "preview": "#version 330\n\nlayout(location=0) in vec2 v_position;\n\n// camera parameters for transforming the object position\n// and s"
  },
  {
    "path": "assets/test/shaders/demo_6_2d_frustum_frame.vert.glsl",
    "chars": 171,
    "preview": "#version 330\n\nlayout(location=0) in vec2 v_position;\n\nvoid main() {\n    // flip the y coordinate in OpenGL\n    gl_Positi"
  },
  {
    "path": "assets/test/shaders/demo_6_3d.frag.glsl",
    "chars": 172,
    "preview": "#version 330\n\nin vec2 tex_pos;\n\nlayout(location=0) out vec4 out_col;\n\nuniform sampler2D tex;\n\nvoid main()\n{\n    vec4 tex"
  },
  {
    "path": "assets/test/shaders/demo_6_3d.vert.glsl",
    "chars": 612,
    "preview": "#version 330\n\nlayout (location = 0) in vec3 position;\nlayout (location = 1) in vec2 uv;\n\nout vec2 tex_pos;\n\n// camera pa"
  },
  {
    "path": "assets/test/shaders/demo_6_display.frag.glsl",
    "chars": 130,
    "preview": "#version 330\n\nuniform sampler2D color_texture;\n\nin vec2 v_uv;\nout vec4 col;\n\nvoid main() {\n\tcol = texture(color_texture,"
  },
  {
    "path": "assets/test/shaders/demo_6_display.vert.glsl",
    "chars": 167,
    "preview": "#version 330\n\nlayout(location=0) in vec2 position;\nlayout(location=1) in vec2 uv;\nout vec2 v_uv;\n\nvoid main() {\n\tgl_Posi"
  },
  {
    "path": "assets/test/shaders/demo_7_shader_command.frag.glsl",
    "chars": 174,
    "preview": "#version 330\n\nin vec2 tex_coord;\nout vec4 frag_color;\n\nuniform float time;\n\nvoid main() {\n\t// PLACEHOLDER: color\n\t// PLA"
  },
  {
    "path": "assets/test/shaders/demo_7_shader_command.vert.glsl",
    "chars": 151,
    "preview": "#version 330\n\nin vec2 position;\nout vec2 tex_coord;\n\nvoid main() {\n\ttex_coord = position.xy * 0.5 + 0.5;\n\tgl_Position = "
  },
  {
    "path": "assets/test/shaders/demo_7_snippets/alpha.snippet",
    "chars": 39,
    "preview": "float alpha = (sin(time) + 1.0) * 0.5;\n"
  },
  {
    "path": "assets/test/shaders/demo_7_snippets/color.snippet",
    "chars": 111,
    "preview": "float r = 0.5 + 0.5 * sin(time);\nfloat g = 0.5 + 0.5 * sin(time + 2.0);\nfloat b = 0.5 + 0.5 * sin(time + 4.0);\n"
  },
  {
    "path": "assets/test/shaders/pathfinding/CMakeLists.txt",
    "chars": 110,
    "preview": "install(DIRECTORY \".\"\n\tDESTINATION \"${ASSET_DIR}/test/shaders/pathfinding\"\n\tFILES_MATCHING PATTERN \"*.glsl\"\n)\n"
  },
  {
    "path": "assets/test/shaders/pathfinding/demo_0_cost_field.frag.glsl",
    "chars": 324,
    "preview": "#version 330\n\nin float v_cost;\n\nout vec4 out_col;\n\nvoid main()\n{\n    if (v_cost == 255.0) {\n        out_col = vec4(0.0, "
  },
  {
    "path": "assets/test/shaders/pathfinding/demo_0_cost_field.vert.glsl",
    "chars": 263,
    "preview": "#version 330\n\nlayout (location = 0) in vec3 position;\nlayout (location = 1) in float cost;\n\nuniform mat4 model;\nuniform "
  },
  {
    "path": "assets/test/shaders/pathfinding/demo_0_display.frag.glsl",
    "chars": 130,
    "preview": "#version 330\n\nuniform sampler2D color_texture;\n\nin vec2 v_uv;\nout vec4 col;\n\nvoid main() {\n\tcol = texture(color_texture,"
  },
  {
    "path": "assets/test/shaders/pathfinding/demo_0_display.vert.glsl",
    "chars": 168,
    "preview": "#version 330\n\nlayout(location=0) in vec2 position;\nlayout(location=1) in vec2 uv;\nout vec2 v_uv;\n\nvoid main() {\n\tgl_Posi"
  },
  {
    "path": "assets/test/shaders/pathfinding/demo_0_flow_field.frag.glsl",
    "chars": 751,
    "preview": "#version 330\n\n/// Flow field value\nin float flow_val;\n\n/// Integration field flags\nin float int_val;\n\nout vec4 outcol;\n\n"
  },
  {
    "path": "assets/test/shaders/pathfinding/demo_0_flow_field.vert.glsl",
    "chars": 352,
    "preview": "#version 330\n\nlayout(location=0) in vec3 position;\nlayout(location=1) in float flow_cell;\nlayout(location=2) in float in"
  },
  {
    "path": "assets/test/shaders/pathfinding/demo_0_grid.frag.glsl",
    "chars": 86,
    "preview": "#version 330\n\nout vec4 out_col;\n\nvoid main()\n{\n\tout_col = vec4(0.0, 0.0, 0.0, 0.3);\n}\n"
  },
  {
    "path": "assets/test/shaders/pathfinding/demo_0_grid.vert.glsl",
    "chars": 188,
    "preview": "#version 330\n\nlayout (location = 0) in vec3 position;\n\nuniform mat4 model;\nuniform mat4 view;\nuniform mat4 proj;\n\nvoid m"
  },
  {
    "path": "assets/test/shaders/pathfinding/demo_0_integration_field.frag.glsl",
    "chars": 278,
    "preview": "#version 330\n\nin float v_cost;\n\nout vec4 out_col;\n\nvoid main()\n{\n    if (v_cost > 512.0) {\n        out_col = vec4(0.0, 0"
  },
  {
    "path": "assets/test/shaders/pathfinding/demo_0_integration_field.vert.glsl",
    "chars": 263,
    "preview": "#version 330\n\nlayout (location = 0) in vec3 position;\nlayout (location = 1) in float cost;\n\nuniform mat4 model;\nuniform "
  },
  {
    "path": "assets/test/shaders/pathfinding/demo_0_obj.frag.glsl",
    "chars": 89,
    "preview": "#version 330\n\nuniform vec4 color;\n\nout vec4 outcol;\n\nvoid main() {\n    outcol = color;\n}\n"
  },
  {
    "path": "assets/test/shaders/pathfinding/demo_0_obj.vert.glsl",
    "chars": 109,
    "preview": "#version 330\n\nlayout(location=0) in vec2 position;\n\nvoid main() {\n\tgl_Position = vec4(position, 0.0, 1.0);\n}\n"
  },
  {
    "path": "assets/test/shaders/pathfinding/demo_0_vector.frag.glsl",
    "chars": 89,
    "preview": "#version 330\n\nuniform vec4 color;\n\nout vec4 outcol;\n\nvoid main() {\n    outcol = color;\n}\n"
  },
  {
    "path": "assets/test/shaders/pathfinding/demo_0_vector.vert.glsl",
    "chars": 185,
    "preview": "#version 330\n\nlayout(location=0) in vec3 position;\n\nuniform mat4 model;\nuniform mat4 view;\nuniform mat4 proj;\n\nvoid main"
  },
  {
    "path": "assets/test/shaders/pathfinding/demo_1_display.frag.glsl",
    "chars": 130,
    "preview": "#version 330\n\nuniform sampler2D color_texture;\n\nin vec2 v_uv;\nout vec4 col;\n\nvoid main() {\n\tcol = texture(color_texture,"
  },
  {
    "path": "assets/test/shaders/pathfinding/demo_1_display.vert.glsl",
    "chars": 168,
    "preview": "#version 330\n\nlayout(location=0) in vec2 position;\nlayout(location=1) in vec2 uv;\nout vec2 v_uv;\n\nvoid main() {\n\tgl_Posi"
  },
  {
    "path": "assets/test/shaders/pathfinding/demo_1_grid.frag.glsl",
    "chars": 86,
    "preview": "#version 330\n\nout vec4 out_col;\n\nvoid main()\n{\n\tout_col = vec4(0.0, 0.0, 0.0, 0.3);\n}\n"
  },
  {
    "path": "assets/test/shaders/pathfinding/demo_1_grid.vert.glsl",
    "chars": 193,
    "preview": "#version 330\n\nlayout (location = 0) in vec2 position;\n\nuniform mat4 model;\nuniform mat4 view;\nuniform mat4 proj;\n\nvoid m"
  },
  {
    "path": "assets/test/shaders/pathfinding/demo_1_obj.frag.glsl",
    "chars": 89,
    "preview": "#version 330\n\nuniform vec4 color;\n\nout vec4 outcol;\n\nvoid main() {\n    outcol = color;\n}\n"
  },
  {
    "path": "assets/test/shaders/pathfinding/demo_1_obj.vert.glsl",
    "chars": 190,
    "preview": "#version 330\n\nlayout(location=0) in vec2 position;\n\nuniform mat4 model;\nuniform mat4 view;\nuniform mat4 proj;\n\nvoid main"
  },
  {
    "path": "assets/test/textures/CMakeLists.txt",
    "chars": 100,
    "preview": "install(DIRECTORY \".\"\n\tDESTINATION \"${ASSET_DIR}/test/textures\"\n\tPATTERN \"CMakeLists.txt\" EXCLUDE\n)\n"
  },
  {
    "path": "assets/test/textures/test_animation.sprite",
    "chars": 535,
    "preview": "# Copyright 2021-2021 the openage authors. See copying.md for legal info.\n# openage sprite definition file\n\nversion 2\n\nt"
  },
  {
    "path": "assets/test/textures/test_gaben.sprite",
    "chars": 212,
    "preview": "# Copyright 2023-2023 the openage authors. See copying.md for legal info.\n# openage sprite definition file\n\nversion 2\n\nt"
  },
  {
    "path": "assets/test/textures/test_gaben.texture",
    "chars": 183,
    "preview": "# Copyright 2023-2023 the openage authors.\n# openage texture definition file\n\nversion 1\n\nimagefile \"gaben.png\"\n\nsize 719"
  },
  {
    "path": "assets/test/textures/test_missing.sprite",
    "chars": 214,
    "preview": "# Copyright 2023-2023 the openage authors. See copying.md for legal info.\n# openage sprite definition file\n\nversion 2\n\nt"
  },
  {
    "path": "assets/test/textures/test_missing.texture",
    "chars": 176,
    "preview": "# Copyright 2023-2023 the openage authors.\n# openage texture definition file\n\nversion 1\n\nimagefile \"missing.png\"\n\nsize 3"
  },
  {
    "path": "assets/test/textures/test_tank.sprite",
    "chars": 402,
    "preview": "# Copyright 2023-2023 the openage authors. See copying.md for legal info.\n# openage sprite definition file\n\nversion 2\n\nt"
  },
  {
    "path": "assets/test/textures/test_tank.texture",
    "chars": 823,
    "preview": "# The image file was adapted from the \"German WW2 isometric pixel tanks\" sprite pack,\n# Copyright 2020-2020 by jh2assets"
  },
  {
    "path": "assets/test/textures/test_tank_mirrored.sprite",
    "chars": 394,
    "preview": "# Copyright 2023-2023 the openage authors. See copying.md for legal info.\n# openage sprite definition file\n\nversion 2\n\nt"
  },
  {
    "path": "assets/test/textures/test_terrain.terrain",
    "chars": 194,
    "preview": "# Copyright 2023-2023 the openage authors. See copying.md for legal info.\n# openage terrain definition file\n\nversion 2\n\n"
  },
  {
    "path": "assets/test/textures/test_terrain.texture",
    "chars": 183,
    "preview": "# Copyright 2023-2023 the openage authors.\n# openage texture definition file\n\nversion 1\n\nimagefile \"test_terrain.png\"\n\ns"
  },
  {
    "path": "assets/test/textures/test_terrain2.terrain",
    "chars": 195,
    "preview": "# Copyright 2023-2023 the openage authors. See copying.md for legal info.\n# openage terrain definition file\n\nversion 2\n\n"
  },
  {
    "path": "assets/test/textures/test_terrain2.texture",
    "chars": 184,
    "preview": "# Copyright 2023-2023 the openage authors.\n# openage texture definition file\n\nversion 1\n\nimagefile \"test_terrain2.png\"\n\n"
  },
  {
    "path": "assets/test/textures/test_texture.texture",
    "chars": 1246,
    "preview": "# The image file was adapted from the \"Elemental Ground Monk\" sprite pack,\n# Copyright 2021-2021 by chierit.\n#\n# It's li"
  },
  {
    "path": "assets/textures/CMakeLists.txt",
    "chars": 95,
    "preview": "install(DIRECTORY \".\"\n\tDESTINATION \"${ASSET_DIR}/textures\"\n\tPATTERN \"CMakeLists.txt\" EXCLUDE\n)\n"
  },
  {
    "path": "assets/textures/torn_paper_edge.docx",
    "chars": 31,
    "preview": "# x,y,w,h,cx,cy\n0,0,512,16,0,0\n"
  },
  {
    "path": "buildsystem/CheckCompilerFeatures.cmake",
    "chars": 1162,
    "preview": "# Copyright 2015-2021 the openage authors. See copying.md for legal info.\n\ninclude(CheckCXXSourceRuns)\n\nif(cxx_thread_lo"
  },
  {
    "path": "buildsystem/CheckInSourceBuild.cmake",
    "chars": 1251,
    "preview": "# Copyright 2015-2018 the openage authors. See copying.md for legal info.\n\nif(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINAR"
  },
  {
    "path": "buildsystem/CheckRuntimeDependencies.cmake",
    "chars": 2006,
    "preview": "# Copyright 2015-2023 the openage authors. See copying.md for legal info.\n\n# python modules\n# a list of imported modules"
  },
  {
    "path": "buildsystem/DependencyFetch.cmake",
    "chars": 2688,
    "preview": "# Copyright 2017-2017 the openage authors. See copying.md for legal info.\n\n# Fetch project with given name from the Inte"
  },
  {
    "path": "buildsystem/DetectProjectVersion.cmake",
    "chars": 1295,
    "preview": "# Copyright 2015-2023 the openage authors. See copying.md for legal info.\n\n# Determines the version of the project\n# sto"
  },
  {
    "path": "buildsystem/HandleCXXOptions.cmake",
    "chars": 6788,
    "preview": "# Copyright 2015-2023 the openage authors. See copying.md for legal info.\n\n# sets CXXFLAGS and compiler for the project\n"
  },
  {
    "path": "buildsystem/HandlePythonOptions.cmake",
    "chars": 3037,
    "preview": "# Copyright 2015-2025 the openage authors. See copying.md for legal info.\n\n# finds the python interpreter, install desti"
  },
  {
    "path": "buildsystem/__init__.py",
    "chars": 321,
    "preview": "# Copyright 2015-2020 the openage authors. See copying.md for legal info.\n\n\"\"\"\nCMake build helpers; see doc/buildsystem."
  },
  {
    "path": "buildsystem/check_py_file_list.py",
    "chars": 2086,
    "preview": "# Copyright 2015-2021 the openage authors. See copying.md for legal info.\n\n\"\"\"\nTests whether the files listed via add_py"
  },
  {
    "path": "buildsystem/codecompliance/__init__.py",
    "chars": 150,
    "preview": "# Copyright 2015-2016 the openage authors. See copying.md for legal info.\n\n\"\"\"\nCode compliance checker module\n\nIntegrate"
  },
  {
    "path": "buildsystem/codecompliance/__main__.py",
    "chars": 10160,
    "preview": "# Copyright 2014-2025 the openage authors. See copying.md for legal info.\n\n\"\"\"\nEntry point for the code compliance check"
  },
  {
    "path": "buildsystem/codecompliance/authors.py",
    "chars": 3122,
    "preview": "# Copyright 2014-2024 the openage authors. See copying.md for legal info.\n\n\"\"\"\nChecks whether all authors are properly l"
  },
  {
    "path": "buildsystem/codecompliance/clangtidy.py",
    "chars": 2160,
    "preview": "# Copyright 2024-2024 the openage authors. See copying.md for legal info.\n\n\"\"\"\nChecks clang-tidy errors on cpp files\n\"\"\""
  },
  {
    "path": "buildsystem/codecompliance/cppstyle.py",
    "chars": 3452,
    "preview": "# Copyright 2015-2017 the openage authors. See copying.md for legal info.\n\n\"\"\"\nChecks some code style rules for cpp file"
  },
  {
    "path": "buildsystem/codecompliance/cython.py",
    "chars": 1834,
    "preview": "# Copyright 2021-2021 the openage authors. See copying.md for legal info.\n\n\"\"\"\nVerifies that Cython directives for profi"
  },
  {
    "path": "buildsystem/codecompliance/headerguards.py",
    "chars": 1270,
    "preview": "# Copyright 2014-2021 the openage authors. See copying.md for legal info.\n\n\"\"\"\nVerifies the guard macros of all C++ head"
  },
  {
    "path": "buildsystem/codecompliance/legal.py",
    "chars": 7035,
    "preview": "# Copyright 2014-2023 the openage authors. See copying.md for legal info.\n\n\"\"\"\nChecks the legal headers of all files.\n\"\""
  },
  {
    "path": "buildsystem/codecompliance/modes.py",
    "chars": 1593,
    "preview": "# Copyright 2016-2022 the openage authors. See copying.md for legal info.\n\n\"\"\"\nChecks the mode of all files and prevents"
  },
  {
    "path": "buildsystem/codecompliance/pylint.py",
    "chars": 1288,
    "preview": "# Copyright 2015-2023 the openage authors. See copying.md for legal info.\n\n\"\"\"\nChecks the Python modules with pylint.\n\"\""
  },
  {
    "path": "buildsystem/codecompliance/pystyle.py",
    "chars": 1280,
    "preview": "# Copyright 2014-2018 the openage authors. See copying.md for legal info.\n\n\"\"\"\nChecks PEP8 compliance, with some excepti"
  },
  {
    "path": "buildsystem/codecompliance/textfiles.py",
    "chars": 2439,
    "preview": "# Copyright 2015-2019 the openage authors. See copying.md for legal info.\n\n\"\"\"\nChecks some general whitespace rules and "
  },
  {
    "path": "buildsystem/codecompliance/util.py",
    "chars": 4292,
    "preview": "# Copyright 2014-2023 the openage authors. See copying.md for legal info.\n\n\"\"\"\nSome utilities.\n\"\"\"\n\nimport logging\nimpor"
  },
  {
    "path": "buildsystem/codegen.cmake",
    "chars": 2862,
    "preview": "# Copyright 2014-2025 the openage authors. See copying.md for legal info.\n\n# set CODEGEN_SCU_FILE to the absolute path t"
  },
  {
    "path": "buildsystem/compilepy.py",
    "chars": 3322,
    "preview": "# Copyright 2015-2022 the openage authors. See copying.md for legal info.\n\n\"\"\"\nCompiles python modules with cpython to p"
  },
  {
    "path": "buildsystem/cpp.cmake",
    "chars": 2973,
    "preview": "# Copyright 2014-2018 the openage authors. See copying.md for legal info.\n\n# declare a new 'empty' executable file.\n# yo"
  },
  {
    "path": "buildsystem/cythonize.py",
    "chars": 8614,
    "preview": "#!/usr/bin/env python3\n#\n# Copyright 2015-2025 the openage authors. See copying.md for legal info.\n\n\"\"\"\nRuns Cython on a"
  },
  {
    "path": "buildsystem/doxygen.cmake",
    "chars": 1630,
    "preview": "# Copyright 2014-2016 the openage authors. See copying.md for legal info.\n\n# Doxygen integration\n\n# enable doxygen for a"
  },
  {
    "path": "buildsystem/doxygen_custom.css",
    "chars": 4197,
    "preview": "/*******************************************************\n * Make footer black and content white\n */\n\nbody {\n\tbackground-"
  },
  {
    "path": "buildsystem/inplacemodules.py",
    "chars": 2134,
    "preview": "# Copyright 2015-2021 the openage authors. See copying.md for legal info.\n\n\"\"\"\nInstalls the Python extension modules tha"
  },
  {
    "path": "buildsystem/modules/DownloadCache.cmake",
    "chars": 824,
    "preview": "# Copyright 2017-2017 the openage authors. See copying.md for legal info.\n\n# DownloadCache, as the name suggests, downlo"
  },
  {
    "path": "buildsystem/modules/FindCython.cmake",
    "chars": 478,
    "preview": "# Copyright 2015-2016 the openage authors. See copying.md for legal info.\n\n# This module defines:\n#\n#  CYTHON_FOUND\n#  C"
  },
  {
    "path": "buildsystem/modules/FindEpoxy.cmake",
    "chars": 596,
    "preview": "# Copyright 2015-2016 the openage authors. See copying.md for legal info.\n\nfind_path(EPOXY_INCLUDE_DIRS epoxy/gl.h\n\tHINT"
  },
  {
    "path": "buildsystem/modules/FindGCCBacktrace.cmake",
    "chars": 1616,
    "preview": "# Copyright 2015-2017 the openage authors. See copying.md for legal info.\n\n# This module defines:\n#\n#  GCCBacktrace_FOUN"
  },
  {
    "path": "buildsystem/modules/FindGPerfTools.cmake",
    "chars": 1777,
    "preview": "# This file was taken from VAST,\n# Copyright 2014-2014 Matthias Vallentin.\n# It's licensed under the terms of the 3-clau"
  },
  {
    "path": "buildsystem/modules/FindHarfBuzz.cmake",
    "chars": 1855,
    "preview": "# Copyright 2015-2016 the openage authors. See copying.md for legal info.\n\n# FindHarfBuzz\n# ---------\n#\n# Locate HarfBuz"
  },
  {
    "path": "buildsystem/modules/FindInotify.cmake",
    "chars": 386,
    "preview": "# Copyright 2014-2020 the openage authors. See copying.md for legal info.\n\n# This module defines\n#\n# INOTIFY_INCLUDE_DIR"
  },
  {
    "path": "buildsystem/modules/FindOgg.cmake",
    "chars": 835,
    "preview": "# Copyright 2018-2018 the openage authors. See copying.md for legal info.\n\n# - Find ogg library\n# Find the native Ogg he"
  },
  {
    "path": "buildsystem/modules/FindOpusfile.cmake",
    "chars": 1604,
    "preview": "# This file was taken from Unvanquished,\n# Copyright 2000-2009 Kitware, Inc., Insight Software Consortium\n# It's license"
  },
  {
    "path": "buildsystem/modules/FindPython.cmake",
    "chars": 5978,
    "preview": "# Copyright 2015-2025 the openage authors. See copying.md for legal info.\n\n# Find Python\n# ~~~~~~~~~~~\n#\n# Find the Pyth"
  },
  {
    "path": "buildsystem/modules/FindPython_test.cpp",
    "chars": 289,
    "preview": "// Copyright 2014-2023 the openage authors. See copying.md for legal info.\n\n#include <Python.h>\n\nint main() {\n\t// set by"
  },
  {
    "path": "buildsystem/options.cmake",
    "chars": 1844,
    "preview": "# Copyright 2014-2018 the openage authors. See copying.md for legal info.\n\n# logs whether the option NAME is enabled\n# s"
  },
  {
    "path": "buildsystem/pxdgen.py",
    "chars": 16016,
    "preview": "# Copyright 2015-2023 the openage authors. See copying.md for legal info.\n\n\"\"\"\nAuto-generates PXD files from annotated C"
  },
  {
    "path": "buildsystem/python.cmake",
    "chars": 19190,
    "preview": "# Copyright 2014-2025 the openage authors. See copying.md for legal info.\n\n# provides macros for defining python extensi"
  },
  {
    "path": "buildsystem/scripts/EmbedFont.cmake",
    "chars": 1057,
    "preview": "# Copyright 2017-2017 the openage authors. See copying.md for legal info.\n\nif(NOT forward_variables)\n\tmessage(FATAL_ERRO"
  },
  {
    "path": "buildsystem/scripts/EmbedPython.cmake",
    "chars": 993,
    "preview": "# Copyright 2017-2022 the openage authors. See copying.md for legal info.\n\nif(NOT forward_variables)\n\tmessage(FATAL_ERRO"
  },
  {
    "path": "buildsystem/scripts/EmbedWinDependencies.cmake",
    "chars": 3408,
    "preview": "# Copyright 2017-2020 the openage authors. See copying.md for legal info.\n\nif(NOT forward_variables)\n\tmessage(FATAL_ERRO"
  },
  {
    "path": "buildsystem/scripts/copy_modules.py",
    "chars": 1313,
    "preview": "# Copyright 2017-2020 the openage authors. See copying.md for legal info.\n\n\"\"\"\nCopies the specified modules to the requi"
  },
  {
    "path": "buildsystem/templates/Doxyfile.in",
    "chars": 105939,
    "preview": "# Doxyfile 1.8.12\n\n# This file describes the settings to be used by the documentation system\n# doxygen (www.doxygen.org)"
  },
  {
    "path": "buildsystem/templates/ExternalFetch.cmake.in",
    "chars": 938,
    "preview": "# Copyright 2017-2017 the openage authors. See copying.md for legal info.\n\n# @AUTOGEN_WARNING@\n\n# Template file because "
  },
  {
    "path": "buildsystem/templates/ForwardVariables.cmake.in",
    "chars": 1056,
    "preview": "# Copyright 2017-2020 the openage authors. See copying.md for legal info.\n\n# @AUTOGEN_WARNING@\n\n# This script passes (fo"
  },
  {
    "path": "buildsystem/templates/openage.bat.in",
    "chars": 275,
    "preview": "@rem Copyright 2017-2017 the openage authors. See copying.md for legal info.\n@echo off\n\nrem @AUTOGEN_WARNING@\n\nset INST_"
  },
  {
    "path": "buildsystem/templates/qt.conf",
    "chars": 62,
    "preview": "[Paths]\nPlugins = ..\\\\bin\\\\plugins\nQml2Imports = ..\\\\bin\\\\qml\n"
  },
  {
    "path": "buildsystem/util.cmake",
    "chars": 1351,
    "preview": "# Copyright 2014-2016 the openage authors. See copying.md for legal info.\n\nset(AUTOGEN_WARNING \"warning: auto-generated "
  },
  {
    "path": "cfg/.gitignore",
    "chars": 15,
    "preview": "asset_location\n"
  },
  {
    "path": "cfg/CMakeLists.txt",
    "chars": 270,
    "preview": "# Copyright 2017-2021 the openage authors. See copying.md for legal info.\n\ninstall(FILES\n\t\"${CMAKE_CURRENT_SOURCE_DIR}/k"
  },
  {
    "path": "cfg/converter/games/aoc/version_hashes.toml",
    "chars": 447,
    "preview": "# version hashes of Age of Empires 2: The Conqueror's\n\nfile_version = \"2.0\"\nhash_algo = \"SHA3-256\"\n\n[age2_x1]\npaths = [\""
  },
  {
    "path": "cfg/converter/games/aoc_demo/version_hashes.toml",
    "chars": 438,
    "preview": "# version hashes of Age of Empires 2: The Conqueror's Demo\n\nfile_version = \"2.0\"\nhash_algo = \"SHA3-256\"\n\n[age2_x1t]\npath"
  },
  {
    "path": "cfg/converter/games/aok/version_hashes.toml",
    "chars": 353,
    "preview": "# version hashes of Age of Empires 2: Age of Kings\n\nfile_version = \"2.0\"\nhash_algo = \"SHA3-256\"\n\n[empires2]\npaths = [\"em"
  },
  {
    "path": "cfg/converter/games/de1/version_hashes.toml",
    "chars": 376,
    "preview": "# version hashes of Age of Empires 1: Definitive Edition (Steam)\n\nfile_version = \"2.0\"\nhash_algo = \"SHA3-256\"\n\n[AoEDE_s]"
  },
  {
    "path": "cfg/converter/games/de2/version_hashes.toml",
    "chars": 410,
    "preview": "# version hashes of Age of Empires 2: Definitive Edition\n\nfile_version = \"2.0\"\nhash_algo = \"SHA3-256\"\n\n[AoE2DE_s]\npaths "
  },
  {
    "path": "cfg/converter/games/game_editions.toml",
    "chars": 10859,
    "preview": "# game edition config file for openage\n\nfile_version = \"1.1\"\n\n[AOC]\nname            = \"Age of Empires 2: The Conqueror's"
  },
  {
    "path": "cfg/converter/games/game_expansions.toml",
    "chars": 1045,
    "preview": "# game expansion config file for openage\n\nfile_version = \"1.0\"\n\n[AFRI_KING]\nname            = \"African Kingdoms (HD)\"\nga"
  },
  {
    "path": "cfg/converter/games/hd/version_hashes.toml",
    "chars": 382,
    "preview": "# version hashes of Age of Empires 2: HD Edition\n\nfile_version = \"2.0\"\nhash_algo = \"SHA3-256\"\n\n[\"AoK HD\"]\npaths = [\"AoK "
  },
  {
    "path": "cfg/converter/games/hd_ak/version_hashes.toml",
    "chars": 255,
    "preview": "# version hashes of African Kingdoms (HD)\n\nfile_version = \"2.0\"\nhash_algo = \"SHA3-256\"\n\n[empires2_x2_p1dat]\npaths = [\"re"
  },
  {
    "path": "cfg/converter/games/hd_fgt/version_hashes.toml",
    "chars": 256,
    "preview": "# version hashes of Forgotten Empires (HD)\n\nfile_version = \"2.0\"\nhash_algo = \"SHA3-256\"\n\n[empires2_x2_p1dat]\npaths = [\"r"
  },
  {
    "path": "cfg/converter/games/hd_raj/version_hashes.toml",
    "chars": 256,
    "preview": "# version hashes of Rise of the Rajas (HD)\n\nfile_version = \"2.0\"\nhash_algo = \"SHA3-256\"\n\n[empires2_x2_p1dat]\npaths = [\"r"
  },
  {
    "path": "cfg/converter/games/ror/version_hashes.toml",
    "chars": 351,
    "preview": "# version hashes of Age of Empires 1: Rise of Rome\n\nfile_version = \"2.0\"\nhash_algo = \"SHA3-256\"\n\n[EMPIRESX]\npaths = [\"EM"
  },
  {
    "path": "cfg/converter/games/swgb/version_hashes.toml",
    "chars": 364,
    "preview": "# version hashes of Star Wars: Galactic Battlegrounds\n\nfile_version = \"2.0\"\nhash_algo = \"SHA3-256\"\n\n[Battlegrounds]\npath"
  },
  {
    "path": "cfg/converter/games/swgb_cc/version_hashes.toml",
    "chars": 369,
    "preview": "# version hashes of Clone Campaigns\n\nfile_version = \"2.0\"\nhash_algo = \"SHA3-256\"\n\n[battlegrounds_x1]\npaths = [\"Game/batt"
  },
  {
    "path": "cfg/keybinds.oac",
    "chars": 1637,
    "preview": "# Copyright 2016-2016 the openage authors. See copying.md for legal info.\n\nset TOGGLE_CONSOLE `\nset START_GAME Return\nse"
  },
  {
    "path": "changelog.md",
    "chars": 317,
    "preview": "# Changelog\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),\nand this project adheres to"
  },
  {
    "path": "configure",
    "chars": 14034,
    "preview": "#!/usr/bin/env python3\n\n# Copyright 2013-2021 the openage authors. See copying.md for legal info.\n\n\"\"\"\nopenage autocance"
  },
  {
    "path": "copying.md",
    "chars": 22994,
    "preview": "Any file in this project that doesn't state otherwise, and isn't listed as an\nexception below, is Copyright 2013-2021 Th"
  }
]

// ... and 1469 more files (download for full content)

About this extraction

This page contains the full source code of the SFTtech/openage GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1669 files (7.2 MB), approximately 2.0M tokens, and a symbol index with 3891 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!