pax_global_header00006660000000000000000000000064132127657620014525gustar00rootroot0000000000000052 comment=5e56a70eb8e563ef3147a058846756b46cbf4fe5 libtcod-1.6.4+dfsg/000077500000000000000000000000001321276576200140745ustar00rootroot00000000000000libtcod-1.6.4+dfsg/.gitattributes000066400000000000000000000016511321276576200167720ustar00rootroot00000000000000#common settings that generally should always be used with your language specific settings # Auto detect text files and perform LF normalization # http://davidlaing.com/2012/09/19/customise-your-gitattributes-to-become-a-git-ninja/ * text=auto # # The above will handle all files NOT found below # # Documents *.doc diff=astextplain *.DOC diff=astextplain *.docx diff=astextplain *.DOCX diff=astextplain *.dot diff=astextplain *.DOT diff=astextplain *.pdf diff=astextplain *.PDF diff=astextplain *.rtf diff=astextplain *.RTF diff=astextplain *.md text *.adoc text *.textile text *.mustache text *.csv text *.tab text *.tsv text *.sql text # Graphics *.png binary *.jpg binary *.jpeg binary *.gif binary *.tif binary *.tiff binary *.ico binary # SVG treated as an asset (binary) by default. If you want to treat it as text, # comment-out the following line and uncomment the line after. *.svg binary #*.svg text *.eps binary libtcod-1.6.4+dfsg/.gitignore000066400000000000000000000034071321276576200160700ustar00rootroot00000000000000## https://github.com/github/gitignore/blob/master/C.gitignore # Prerequisites *.d # Object files *.o *.ko *.obj *.elf # Linker output *.ilk *.map *.exp # Precompiled Headers *.gch *.pch # Libraries *.lib *.a *.la *.lo # Shared objects (inc. Windows DLLs) *.dll *.so *.so.* *.dylib # Executables *.exe *.out *.app *.i*86 *.x86_64 *.hex # Debug files *.dSYM/ *.su *.idb *.pdb # Kernel Module Compile Results *.mod* *.cmd modules.order Module.symvers Mkfile.old dkms.conf ## https://github.com/github/gitignore/blob/master/SCons.gitignore # for projects that use SCons for building: http://http://www.scons.org/ .sconsign.dblite ## https://github.com/github/gitignore/blob/master/Python.gitignore # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python env/ build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ *.egg-info/ .installed.cfg *.egg # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *,cover .hypothesis/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # Jupyter Notebook .ipynb_checkpoints # pyenv .python-version # celery beat schedule file celerybeat-schedule # SageMath parsed files *.sage.py # dotenv .env # virtualenv .venv venv/ ENV/ # Spyder project settings .spyderproject # Rope project settings .ropeproject libtcod-1.6.4+dfsg/.hg_archival.txt000066400000000000000000000001711321276576200171610ustar00rootroot00000000000000repo: 5b845890757fadf27a11843a5cbfbbf9e04721d5 node: da8dc60f51bca44f2af96d62dd9bc3d7c9123195 branch: default tag: 1.6.4 libtcod-1.6.4+dfsg/.hgignore000066400000000000000000000004301321276576200156740ustar00rootroot00000000000000syntax: regexp build/dependencies build/packages doc/_build \.vcproj$ \.vcxproj.user$ cbproj xcodeproj libtcod.build CMakeFiles CMakeScripts .*\.cmake$ Makefile$ .*\.dylib$ .*/[Release|Debug] CMakeCache.txt \.a$ \.egg-info/ __pycache__ \.py[co] \.deps/ \.dirstamp \.o \.lo \.suo libtcod-1.6.4+dfsg/.hgtags000066400000000000000000000010521321276576200153500ustar00rootroot00000000000000d56ffc19afb945c49f4794bf21970eb05692e24a 1.5.1 54a11d9daed3c4bd76c9a051ab61fcf9a58ea8a5 edge_of_the_cliff 532f22d0e6da425928a7391889ad13a791addfe9 1.6.0-pre1 532f22d0e6da425928a7391889ad13a791addfe9 1.6.0-pre1 0000000000000000000000000000000000000000 1.6.0-pre1 0000000000000000000000000000000000000000 1.6.0-pre1 40125c08ce3c9ec025d60b4f5aca0a9ef418f8f7 1.6.0-pre1 11ebfc844244f1ed464bccd012ce907825075711 1.6.0 f01cd31b3124937d62a892647309104aba767010 1.6.1 855a3721c7d5ad5e6b4a7f5945ada34e0fe44c3e 1.6.2 2adc592d7727a8923d166a5cd1bb8ab239260589 1.6.3 libtcod-1.6.4+dfsg/.travis.yml000066400000000000000000000012561321276576200162110ustar00rootroot00000000000000language: python python: - "2.7" - "3.3" os: linux matrix: include: - os: osx language: generic sudo: required dist: trusty addons: apt: packages: - libsdl2-dev - scons before_install: # Start X11 display on Linux - 'if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export DISPLAY=:99.0; fi' - 'if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sh -e /etc/init.d/xvfb start; fi' # Install SCons on MacOS via pip - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then pip install --egg scons; fi install: - cd build/scons - scons develop dist -j 3 ARCH=x86_64 - cd ../.. before_script: - pip install pytest pytest-cov - cd python - python setup.py develop script: - pytest -v libtcod-1.6.4+dfsg/LIBTCOD-CREDITS.txt000066400000000000000000000037541321276576200170210ustar00rootroot00000000000000Products : - zlib 1.2.8, by Jean-loup Gailly and Mark Adler http://www.zlib.org - lodepng 20160501, by Lode Vandevenne http://lodev.org/lodepng - SDL 2, by Sam Lantinga http://www.libsdl.org Many thanks to everyone who provided feedback and patches, and especially : - Dominik 'Mingos' Marczuk for the restrictive shadowcasting fov, djikstra pathfinding, name generator, documentation skin, lots of bitmap fonts and being the #1 libtcod user, supporter and contributor. - Joao 'Jotaf' Henriques for his long time support, priceless comments and suggestions and the awesome Python tutorial. - Chris 'donblas' Hamons for libtcod-net, the cmake system, the swig wrappers... - Jonathon Duerig for the permissive field of view algorithm - dividee for polishing and optimizing the Python wrapper. - John Klimek for the early C# port and valuable bug fixes. - Kyle 'Hex Decimal' Stewart & Emmanuel 'Altefcat' Dempur for their contribution to the Python port. - Antagonist for the awesome SkyFire GLSL roguelike engine, hence libtcod's GLSL renderer - Sandman for various tricky bug fixes. - Joe Osborn for the OSX port, bug fixes and the bresenham 3d routines (still to be backported from the old 1.5 branch...). - Paul Sexton for the common Lisp wrapper. - Bernard Helyer for the D wrapper. - Adam 'Blinks' Blinkinsop for the OSX port and the autotools compilation system. - Nick Glauber for being the first libtcod Paypal sponsor. - Matt Sullivan for the py3k support - namor for the FreeBSD cmake support - Anylo for putting some of the demos in the cmake compilation - Michael De Rosa, Killer_X and Joe Rumsey for their work on OSX port - Denis Belov for fixes on the heightmap toolkit - owners of projects using libtcod. Fonts : The celtic garamond and dundalk fonts are from 1001freefonts.com. The caeldera font is from blambot.com. Other fonts are included in windows. The celtic_garamond, arial, courier, dejavu, consolas, prestige and lucida 10x10/12x12 bitmap fonts were created by Mingos. libtcod-1.6.4+dfsg/LIBTCOD-LICENSE.txt000066400000000000000000000032351321276576200170000ustar00rootroot00000000000000* libtcod 1.6.3 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * libtcod 'The Doryen library' is a cross-platform C/C++ library for roguelike * developers. * Its source code is available from : * http://doryen.eptalys.net/libtcod * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE AND MINGOS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE OR MINGOS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. libtcod-1.6.4+dfsg/README-linux-SDL2.md000066400000000000000000000040231321276576200172110ustar00rootroot00000000000000Building Libtcod 1.6 on Linux with SDL2 ======================================= The following instructions have been tested on 32 and 64-bit versions of Ubuntu 14.04 and Fedora 22. Dependencies ------------ For Ubuntu 14.04, install these dependencies: $ sudo apt-get install curl build-essential make cmake autoconf automake libtool mercurial libasound2-dev libpulse-dev libaudio-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxinerama-dev libxxf86vm-dev libxss-dev libgl1-mesa-dev libesd0-dev libdbus-1-dev libudev-dev libgles1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev For Fedora 22: $ sudo dnf -v groupinstall "C Development Tools and Libraries" $ sudo dnf install mercurial alsa-lib-devel audiofile-devel mesa-libGL-devel mesa-libGLU-devel mesa-libEGL-devel mesa-libGLES-devel libXext-devel libX11-devel libXi-devel libXrandr-devel libXrender-devel dbus-devel libXScrnSaver-devel libusb-devel pulseaudio-libs-devel libXinerama-devel libXcursor-devel systemd-devel Building SDL2 ------------- It is recommended strongly that you install SDL2 using your package manager. However, if you are unable to work out the package name, then you can take the harder route and build it yourself. Download the supported SDL2 revision, build and install it if you must: $ curl -o sdl.tar.gz http://hg.libsdl.org/SDL/archive/007dfe83abf8.tar.gz $ tar -xf sdl.tar.gz $ cd SDL-007dfe83abf8/ $ mkdir -p build $ cd build $ ../configure $ make $ sudo make install This will place the libraries at `/usr/local/lib/` and the development headers at `/usr/local/include/SDL2/`. Building Libtcod 1.6 -------------------- Download the latest libtcod version, build it and install it: $ hg clone https://bitbucket.org/libtcod/libtcod $ cd libtcod/build/autotools $ autoreconf -i # if building from hg $ ./configure CFLAGS='-O2' $ make This will place the libraries in the top level of the libtcod checkout directory. Note that the same makefile is used for 32 and 64 bit distributions. libtcod-1.6.4+dfsg/README.md000066400000000000000000000137321321276576200153610ustar00rootroot00000000000000[TOC] ## Introduction ## libtcod is a free, fast, portable and uncomplicated API for roguelike developers providing an advanced true color console, input, and lots of other utilities frequently used in roguelikes. 1.6.5 (pre-release): [![Build status](https://ci.appveyor.com/api/projects/status/6jh07hq205iy0mlh/branch/default?svg=true)](https://ci.appveyor.com/project/rmtew/libtcod/branch/default) ## What can it do? ## If you want to get a quick overview of the features that libtcod provides, check out the [Features](https://bitbucket.org/libtcod/libtcod/wiki/Features) page. If you want to get a quick overview of games which have used libtcod, check out the [Projects](http://roguecentral.org/doryen/projects-2/) page. libtcod is also well known for it's [easy to follow tutorial](http://www.roguebasin.com/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod), which many people have used to get started developing a roguelike. Follow the relevant links the tutorial gives, and it will point you to the right locations. ## How do I get set up? ## ### Using one of our downloads ### Currently, only Windows binaries are available from the Bitbucket [download section](https://bitbucket.org/libtcod/libtcod/downloads) for this project. If you are programming in C or C++, various sample projects are included within the source code which can be used as examples of various features. For those who wish to program in Python which is the only scripting language support that has been contributed so far, the basics are described in [part 1](http://www.roguebasin.com/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_1#Setting_it_up) of the tutorial. Two builds are currently provided for each release: * 32 bit (Win32, SDL2 only) binaries also including source code. * 64 bit (x64, SDL2 only) binaries also including source code. **Warning:** If you download these builds, run `samples.exe` as your very first action. If you are unable to and get an error about `vcruntime140.dll` being missing, you need to install the two [Visual Studio 2015 runtimes](https://www.microsoft.com/en-us/download/details.aspx?id=53587). Make sure you install the 32-bit runtime. And make sure you also install the 64-bit runtime. Then run `samples.exe` again, and it should now work. Whether you plan to develop in C, C++, Python or some other language, this is required. ### Compiling from source ### These are the recommended places to obtain the source code from: * The latest source code release snapshot on the [downloads page](https://bitbucket.org/libtcod/libtcod/downloads). * Clone the repository with Mercurial and checkout the tag for the latest version in the `default` branch. * Clone the repository and checkout the bleeding edge from the tip in the default branch. All compilation methods, currently including Visual Studio (Windows), SCons (Windows, Linux, MacOS) and autotools (Linux, MacOS), are located within the `build/` subdirectory. Windows users who prefer to use Visual Studio directly can either run the top-level 'build.bat' script, or locate and open the provided solution directly using Visual Studio. The solution is currently for Visual Studio 2015, and the [free community edition](https://www.visualstudio.com/vs/community/) is highly recommended. Autotools is a standard approach used for decades, and if you are not familiar with it, you can Bing (or Google) the topic and learn more. Explicit instructions for Linux, which should be relevant, are [provided here](README-linux-SDL2.md). SCons is another popular approach, and explicit instructions are [provided here](https://bitbucket.org/libtcod/libtcod/src/tip/build/scons/?at=default) for those who prefer. MacOS users with a working Homebrew installation, can install the necessary dependencies with `brew install autoconf automake libtool pkg-build sdl2`. To build from the current development version of libtcod (rather than downloading a source package), `brew install mercurial`. Then follow [the directions](README-linux-SDL2.md) for building libtcod on Linux (just the final section). Note that the actual libraries will be in libtcod/build/autotools/.lib, with several symlinks. #### SDL2 #### [SDL2](http://hg.libsdl.org/SDL) is the latest version of SDL. Release 2.0.5 (changeset 007dfe83abf8) of SDL2, is currently used for the official Windows builds. If you choose to use a different version of SDL2, please be sure to mention it in any issues you create. And if you are using the bleeding edge (the latest unreleased/untagged changes), please rule out that this is the cause of any problems you encounter, before creating issues. ## Getting Started ## The latest documentation is updated with every significant change made to libtcod. You can find it in [the doc directory](https://bitbucket.org/libtcod/libtcod/src/tip/doc/index2.html?at=default&fileviewer=file-view-default). Similarly, [the changelog]()https://bitbucket.org/libtcod/libtcod/src/tip/libtcod-CHANGELOG.txt?at=default provides a high level overview of the things you might need to be aware of when later updating libtcod. libtcod comes with a sample application, implementations of which are provided in each of C ([samples_c.c](https://bitbucket.org/libtcod/libtcod/src/tip/samples/samples_c.c?at=default)), C++ ([samples_cpp.cpp](https://bitbucket.org/libtcod/libtcod/src/tip/samples/samples_cpp.cpp?at=default)) and Python ([samples_py.py](https://bitbucket.org/libtcod/libtcod/src/tip/python/samples_py.py?at=default)). This provides a decent overview of the basic features, in an interactive fashion. Each should be identical for the most part, so if you are using Windows, downloading the precompiled binaries and running the included `samples.exe` which is compiled from the C source code, should be representative of the other versions. The popular [Python tutorial](http://www.roguebasin.com/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod) is a good way to both build up a simple roguelike, and get familiar with the basics of libtcod.libtcod-1.6.4+dfsg/appveyor.yml000066400000000000000000000035621321276576200164720ustar00rootroot00000000000000version: 1.0.{build} environment: SCONSMODE: "MODE=DEBUG" matrix: - SCONSOPTS: "ARCH=x86_64 TOOLSET=msvc" TEST_PYTHON2: "C:/Python27-x64/python.exe" TEST_PYTHON3: "C:/Python33-x64/python.exe" - SCONSOPTS: "ARCH=x86 TOOLSET=msvc" TEST_PYTHON2: "C:/Python27/python.exe" TEST_PYTHON3: "C:/Python33/python.exe" - SCONSOPTS: "ARCH=x86_64 TOOLSET=mingw -j 3" INSTALL_MINGW_64: yes TEST_PYTHON2: "C:/Python27-x64/python.exe" TEST_PYTHON3: "C:/Python33-x64/python.exe" - SCONSOPTS: "ARCH=x86 TOOLSET=mingw -j 3" TEST_PYTHON2: "C:/Python27/python.exe" TEST_PYTHON3: "C:/Python33/python.exe" - DEFAULT_BUILD: yes build_script: # Replace MinGW with MinGW64 if INSTALL_MINGW_64 is defined. - cmd: if defined INSTALL_MINGW_64 rmdir /S /Q C:\MinGW - cmd: if defined INSTALL_MINGW_64 choco install mingw - cmd: refreshenv # SCons will build in release mode on a tag push. - cmd: if defined APPVEYOR_REPO_TAG_NAME set SCONSMODE=MODE=RELEASE VERSION=%APPVEYOR_REPO_TAG_NAME% # Install and run scons when there are any SCONSOPTS. - cmd: if defined SCONSOPTS C:/Python27/python.exe -m pip install --upgrade pip distribute setuptools - cmd: if defined SCONSOPTS C:/Python27/python.exe -m pip install --egg scons - cmd: if defined SCONSOPTS cd build/scons - cmd: if defined SCONSOPTS scons develop dist %SCONSMODE% %SCONSOPTS% - cmd: if defined SCONSOPTS cd ../.. # Call build.bat on a DEFAULT_BUILD. - cmd: if defined DEFAULT_BUILD build.bat -d -p -r test_script: - cmd: cd python - cmd: if defined TEST_PYTHON2 %TEST_PYTHON2% -m pip install -U pytest pytest-cov - cmd: if defined TEST_PYTHON2 %TEST_PYTHON2% -m pytest -v - cmd: if defined TEST_PYTHON2 %TEST_PYTHON3% -m pip install -U pytest pytest-cov - cmd: if defined TEST_PYTHON3 %TEST_PYTHON3% -m pytest -v artifacts: - path: build\scons\libtcod-*.zip - path: build\packages\libtcod-*.7z libtcod-1.6.4+dfsg/build.bat000066400000000000000000001124461321276576200156730ustar00rootroot00000000000000<# : @IF "!CI!" NEQ "True" ECHO OFF setlocal EnableDelayedExpansion REM Copyright 2015 Richard Tew REM This script is intended to automate building of libtcod on Windows. REM TODO: appveyor publish build dependencies REM TODO: replace branch name with libtcod version in release package file name REM TODO: Put commit id in release package file name. REM Divert to the internal setup code, it will return to the user setup. goto internal_function_setup REM --- FUNCTION: user_function_setup ---------------------------------------- :user_function_setup REM This function is provided for the user to define what resources this script should REM fetch and help prepare. How they are actually prepared, the user specifies by REM adding support below in 'user_function_prepare_dependency'. REM REM __ LINKS entries are either URLs to ZIP archives, or a collection of version control (vcs) information. REM LINKS[n]= REM LINKS[n]=vcs REM : This can be a URL, or it can be a filesystem path to an existing local clone. REM TODO(rmtew): Comment out local git repositories and replace with remote ones before committing. REM set LINKS[0]=vcs hg SDL2 007dfe83abf8 http://hg.libsdl.org/SDL http://hg.libsdl.org/SDL/archive/REV.zip REM set LINKS[0]=vcs hg SDL2 007dfe83abf8 C:\RMT\VCS\HG\libraries\SDL http://hg.libsdl.org/SDL/archive/ set LINKS[0]=https://www.libsdl.org/release/SDL2-devel-2.0.5-VC.zip set LINKS[1]=https://www.libsdl.org/release/SDL2-2.0.5-win32-x86.zip set LINKS[2]=https://www.libsdl.org/release/SDL2-2.0.5-win32-x64.zip set LINKS[3]= if "!SDL2LINK!" NEQ "" set LINKS[0]=!SDL2LINK! REM __ MD5CHECKSUMS entries are the MD5 checksum for the download in the matching LINKS position REM To get the checksum for a newly added download to add to an entry here, simply run the script and when REM the download is processed, the calculated checksum will be printed and noted as unchecked. set MD5CHECKSUMS[0]=B7-71-F3-6B-B6-40-C1-73-E5-3F-A8-25-9C-DD-38-35 set MD5CHECKSUMS[1]=8B-F6-66-88-2E-6D-4A-4E-89-F9-87-26-E0-22-42-81 set MD5CHECKSUMS[2]=C4-DC-72-7B-13-D4-09-2E-B7-50-99-70-DA-3D-C4-1E set UV_INCLUDE_PATH=!DEPENDENCY_PATH!\include set UV_INCLUDE_COMMANDS[0]= set /A UV_INCLUDE_COMMAND_COUNT=0 set UV_PACKAGES_DIRNAME=packages set UV_PACKAGES_PATH=!BUILD_PATH!\packages REM Allow the user to specify the path to their Git 'git' executable. It may have to be accessed via absolute path. if not defined PYTHON_EXE ( set "PATH=C:\Python27;%PATH%" python.exe --help >nul 2>&1 && (set PYTHON_EXE=python.exe) || (set PYTHON_EXE=) ) REM Get the date in a form YYYYMMDD call :internal_function_get_date set UV_DATE=!V_RESULT! if not defined UV_BUILD_ID ( for /F "usebackq tokens=*" %%A in (`hg id`) do ( set UV_BUILD_ID=%%A ) ) if not defined UV_PACKAGE_RELEASE_DIRNAME ( if defined APPVEYOR ( if defined APPVEYOR_REPO_TAG_NAME ( set UV_PACKAGE_RELEASE_DIRNAME=!APPVEYOR_PROJECT_NAME!-msvs-!APPVEYOR_REPO_TAG_NAME! ) else ( set UV_PACKAGE_RELEASE_DIRNAME=!APPVEYOR_PROJECT_NAME!-msvs-latest-unstable-build ) ) else ( set UV_PACKAGE_RELEASE_DIRNAME=libtcod-msvs ) ) REM Process the user data, calling event functions when applicable. goto:eof REM return REM --- FUNCTION: user_function_prepare_dependency -------------------------------- :user_function_prepare_dependency REM variable: %V_LINK_PARTS% - The link data. REM variable: %DEPENDENCY_PATH% - The absolute path of the dependencies directory. REM variable: %V_DIRNAME% - The relative directory name the dependency can be found in. REM variable: %V_SKIPPED% - 'yes' or 'no', depending on whether the archive was already extracted. set /A L_SDL2_ATTEMPTS=0 :user_function_prepare_dependency_retry cd "!DEPENDENCY_PATH!" if "!V_LINK_PARTS[%LINK_CLASSIFIER%]!" EQU "https" ( if "!V_LINK_PARTS[%HTTP_FILENAME%]!" EQU "SDL2-devel-2.0.5-VC.zip" ( set UV_INCLUDE_COMMANDS[!UV_INCLUDE_COMMAND_COUNT!]=!V_DIRNAME!\SDL2-2.0.5\include\*.h set /A UV_INCLUDE_COMMAND_COUNT=!UV_INCLUDE_COMMAND_COUNT!+1 for %%P in (Win32 x64) do ( SET L_PLATFORM=%%P if "%%P" EQU "Win32" SET L_PLATFORM=x86 if not exist "!DEPENDENCY_PATH!\%%P\Debug" mkdir !DEPENDENCY_PATH!\%%P\Debug if not exist "!DEPENDENCY_PATH!\%%P\Release" mkdir !DEPENDENCY_PATH!\%%P\Release copy >nul !V_DIRNAME!\SDL2-2.0.5\lib\!L_PLATFORM!\SDL2.dll "!DEPENDENCY_PATH!\%%P\Debug\" copy >nul !V_DIRNAME!\SDL2-2.0.5\lib\!L_PLATFORM!\SDL2.lib "!DEPENDENCY_PATH!\%%P\Debug\" copy >nul !V_DIRNAME!\SDL2-2.0.5\lib\!L_PLATFORM!\SDL2.lib "!DEPENDENCY_PATH!\%%P\Release\" ) cd !DEPENDENCY_PATH! ) else if "!V_LINK_PARTS[%HTTP_FILENAME%]!" EQU "SDL2-2.0.5-win32-x64.zip" ( if not exist "!DEPENDENCY_PATH!\x64\Release" mkdir !DEPENDENCY_PATH!\x64\Release copy >nul !V_DIRNAME!\SDL2.dll "!DEPENDENCY_PATH!\x64\Release\" cd !DEPENDENCY_PATH! ) else if "!V_LINK_PARTS[%HTTP_FILENAME%]!" EQU "SDL2-2.0.5-win32-x86.zip" ( if not exist "!DEPENDENCY_PATH!\Win32\Release" mkdir !DEPENDENCY_PATH!\Win32\Release copy >nul !V_DIRNAME!\SDL2.dll "!DEPENDENCY_PATH!\Win32\Release\" cd !DEPENDENCY_PATH! ) else ( echo ERROR.. !V_LINK_PARTS[%HTTP_FILENAME%]! not handled by user who wrote the build amendments. goto internal_function_exit ) ) else if "!V_LINK_PARTS[%LINK_CLASSIFIER%]!" EQU "vcs" ( set L_VCS_NAME=!V_LINK_PARTS[%VCS_NAME%]! if "!L_VCS_NAME!" EQU "SDL2" ( REM This variable is required by the libtcod makefile. set SDL2PATH=!DEPENDENCY_PATH!\!V_DIRNAME! cd !V_DIRNAME! REM TODO(rmtew): Allow user filtering for specific configurations and platforms. for %%P in (Win32 x64) do ( if not exist "!DEPENDENCY_PATH!\%%P" mkdir "!DEPENDENCY_PATH!\%%P" for %%C in (Debug Release) do ( set "SDL2BUILDPATH=!DEPENDENCY_PATH!\%%P\%%C" if not exist "!SDL2BUILDPATH!" mkdir "!SDL2BUILDPATH!" if exist "!SDL2BUILDPATH!\SDL2.dll" ( echo Building: [SDL2^|%%C^|%%P] .. skipped ) else ( echo Building: [SDL2^|%%C^|%%P] REM SDL2 in theory requires the DirectX SDK to be installed, but in practice it's absence REM can be worked around by putting a dummy include file in place, and then only XAudio2 REM support is lost. set L_ERROR_MSG= devenv /upgrade VisualC\SDL.sln for /F "usebackq tokens=*" %%i in (`msbuild /nologo VisualC\SDL.sln /p:Configuration^=%%C /p:Platform^=%%P /t:SDL2^,SDL2main`) do ( set L_LINE=%%i if "!CI!" EQU "True" echo %%i if "!L_LINE:fatal error=!" NEQ "!L_LINE!" set L_ERROR_MSG=%%i ) set /A L_SDL2_ATTEMPTS=!L_SDL2_ATTEMPTS!+1 if exist VisualC\%%P\%%C\SDL2.dll ( echo Copying: [SDL2^|%%C^|%%P] copy >nul VisualC\%%P\%%C\SDL2.dll "!SDL2BUILDPATH!\" copy >nul VisualC\%%P\%%C\SDL2.lib "!SDL2BUILDPATH!\" copy >nul VisualC\%%P\%%C\SDL2.pdb "!SDL2BUILDPATH!\" ) else ( REM Only try and recover from the DirectX problem, and if that don't work, give up. if "!L_ERROR_MSG!" NEQ "" ( if !L_SDL2_ATTEMPTS! EQU 1 ( if "!L_ERROR_MSG:dxsdkver=!" NEQ "!L_ERROR_MSG!" ( echo WARNING: Attempting workaround for missing DirectX SDK [disabling XAudio2] type nul > include\dxsdkver.h goto user_function_prepare_dependency_retry ) ) ) echo ERROR.. SDL2.dll did not successfully build for some reason. goto internal_function_exit ) ) ) ) set UV_INCLUDE_COMMANDS[%UV_INCLUDE_COMMAND_COUNT%]=!V_DIRNAME!\include\*.h set /A UV_INCLUDE_COMMAND_COUNT=%UV_INCLUDE_COMMAND_COUNT%+1 ) else ( echo ERROR.. !V_LINK_PARTS[%VCS_NAME%]! not handled by user who wrote the build amendments. goto internal_function_exit ) ) goto:eof REM return REM --- FUNCTION: user_function_prepare_dependencies ------------------------- :user_function_prepare_dependencies REM description: This is called as a final step after all dependencies have been prepared. REM variable: %DEPENDENCY_PATH% - The absolute path of the dependencies directory. if exist "!UV_INCLUDE_PATH!" goto exit_from_user_function_prepare_dependencies set /A L_COUNT=0 :loop_user_function_prepare_dependencies if %L_COUNT% LSS %UV_INCLUDE_COMMAND_COUNT% ( echo Copying includes: !UV_INCLUDE_COMMANDS[%L_COUNT%]! xcopy >nul /Q /Y "!DEPENDENCY_PATH!\!UV_INCLUDE_COMMANDS[%L_COUNT%]!" "%UV_INCLUDE_PATH%\" set /A L_COUNT=%L_COUNT%+1 goto loop_user_function_prepare_dependencies ) :exit_from_user_function_prepare_dependencies goto:eof REM --- FUNCTION: user_function_build_project -------------------------------- :user_function_build_project set TCOD_SLN_PATH=!BUILD_PATH!\msvs for %%P in (Win32 x64) do ( for %%C in (Debug Release) do ( set L_ERROR_MSG= for /F "usebackq tokens=*" %%i in (`msbuild /nologo msvs\libtcod.sln /p:Configuration^=%%C /p:Platform^=%%P`) do ( set L_LINE=%%i if "!CI!" EQU "True" echo %%i if "!L_LINE:fatal error=!" NEQ "!L_LINE!" set L_ERROR_MSG=%%i ) if "!L_ERROR_MSG!" NEQ "" ( echo ERROR.. libtcod did not successfully build for some reason. goto internal_function_exit ) ) ) goto:eof REM return REM --- FUNCTION: user_function_make_release --------------------------------- :user_function_make_release cd "!BUILD_PATH!" REM Windows defender or something holds onto a file handle. Retry.. set /A L_COUNT=0 for /L %%I in (1,1,5) do ( if exist "!UV_PACKAGES_DIRNAME!" ( rmdir /S /Q "!UV_PACKAGES_DIRNAME!" 2> nul set /A L_COUNT=!L_COUNT!+1 ) ) if exist "!UV_PACKAGES_DIRNAME!" ( echo Failed to purge old release directory: !UV_PACKAGES_DIRNAME! goto internal_function_exit ) mkdir "!UV_PACKAGES_DIRNAME!" cd "!UV_PACKAGES_DIRNAME!" REM Do binary releases for all platforms. for %%P in (Win32 x64) do ( echo Making release: !UV_PACKAGE_RELEASE_DIRNAME!-%%P set "L_RELEASE_PATH=!UV_PACKAGE_RELEASE_DIRNAME!-%%P" REM Start with a verbatim copy of the repository. hg archive -t files !L_RELEASE_PATH! del !L_RELEASE_PATH!\.* del !L_RELEASE_PATH!\*.yml set L_FILES_FILENAME=!L_RELEASE_PATH!\WHERE-ARE-THE-PREBUILT-FILES.txt echo. > !L_FILES_FILENAME! echo These files are placed where Visual Studio expects to find them if you compile the solution:> !L_FILES_FILENAME! echo. > !L_FILES_FILENAME! echo SDL2 includes:>> !L_FILES_FILENAME! echo !DEPENDENCY_DIRNAME!\include\>> !L_FILES_FILENAME! echo. >> !L_FILES_FILENAME! REM Copy the dependencies into place for compilation. xcopy /I /E >nul "!BUILD_PATH!\dependencies\include" "!L_RELEASE_PATH!\!BUILD_DIRNAME!\dependencies\include\" xcopy /I /E >nul "!BUILD_PATH!\dependencies\%%P" "!L_RELEASE_PATH!\!BUILD_DIRNAME!\dependencies\%%P\" for %%C in (Debug Release) do ( for %%N in (libtcod_bare libtcod_sdl_opengl libtcod_sdl libtcod-gui) do ( echo %%C %%P %%N:>> !L_FILES_FILENAME! set L_BASENAME=%%N set L_BASENAME=!L_BASENAME:libtcod_=! if not !L_BASENAME! == %%N ( set L_BASENAME=libtcod ) for %%S in (dll pdb lib) do ( xcopy /I /E >nul "!BUILD_PATH!\msvs\%%N\%%P\%%C\!L_BASENAME!.%%S" "!L_RELEASE_PATH!\!BUILD_DIRNAME!\msvs\%%N\%%P\%%C\*" echo !BUILD_DIRNAME!\msvs\%%N\%%P\%%C\!L_BASENAME!.%%S>> !L_FILES_FILENAME! REM Delete useless automatically copied files. if exist "!L_RELEASE_PATH!\!BUILD_DIRNAME!\msvs\%%N\%%P\%%C\%%N.tlog" ( rmdir /q /s "!L_RELEASE_PATH!\!BUILD_DIRNAME!\msvs\%%N\%%P\%%C\%%N.tlog" ) ) echo. >> !L_FILES_FILENAME! ) ) REM Copy release dlls into the top level directory so the samples can be run directly. copy >nul "!BUILD_PATH!\dependencies\%%P\Release\SDL2.dll" "!L_RELEASE_PATH!\" copy >nul "!BUILD_PATH!\msvs\libtcod_sdl_opengl\%%P\Release\libtcod.dll" "!L_RELEASE_PATH!\" copy >nul "!BUILD_PATH!\msvs\libtcod-gui\%%P\Release\libtcod-gui.dll" "!L_RELEASE_PATH!\" REM Copy the featured sample and the documentation generator. copy >nul "!BUILD_PATH!\msvs\samples_c\%%P\Release\samples_c.exe" "!L_RELEASE_PATH!\samples.exe" copy >nul "!BUILD_PATH!\msvs\doctcod\%%P\Release\doctcod.exe" "!L_RELEASE_PATH!\" REM Record the release path, so the packaging stage can be rerun. echo !L_RELEASE_PATH!>>index.txt ) echo Making extras snapshot: !UV_PACKAGE_RELEASE_DIRNAME!-extras set "L_RELEASE_PATH=!UV_PACKAGE_RELEASE_DIRNAME!-extras" mkdir !L_RELEASE_PATH! set L_FILES_FILENAME=!L_RELEASE_PATH!\HOW-TO-RUN-THESE-FILES.txt echo. > !L_FILES_FILENAME! echo Download either of the Win32 or x64 builds, and copy the exe you want to run into it's root directory.>> !L_FILES_FILENAME! echo. >> !L_FILES_FILENAME! for %%P in (Win32 x64) do ( for %%C in (Release Debug) do ( for %%N in (samples_cpp frost navier rad ripples weather) do ( set "L_RELPATH=%%N\%%P\%%C" mkdir "!L_RELEASE_PATH!\!L_RELPATH!" for %%X in (exe dll) do ( if exist "!BUILD_PATH!\msvs\!L_RELPATH!\%%N.%%X" ( copy >nul "!BUILD_PATH!\msvs\!L_RELPATH!\%%N.%%X" "!L_RELEASE_PATH!\!L_RELPATH!\" if "%%X" EQU "dll" ( copy >nul "!BUILD_PATH!\msvs\!L_RELPATH!\%%N.lib" "!L_RELEASE_PATH!\!L_RELPATH!\" ) ) ) copy >nul "!BUILD_PATH!\msvs\!L_RELPATH!\%%N.pdb" "!L_RELEASE_PATH!\!L_RELPATH!\" ) ) ) REM Record the release path, so the packaging stage can be rerun. echo !L_RELEASE_PATH!>>index.txt cd "!BUILD_PATH!" :exit_from_user_function_make_release goto:eof REM return REM --- FUNCTION: user_function_package_release ------------------------------ :user_function_package_release cd "!BUILD_PATH!\!UV_PACKAGES_DIRNAME!" REM The make release stage will have recorded release directories in 'index.txt'. for /F "usebackq tokens=*" %%I in (index.txt) do ( echo Packaging release: %%I !7Z_EXE! a -r -t7z -mx9 %%I.7z %%I\* if defined APPVEYOR ( REM rmtew -- This seems to error with 'appveyor' command not found. But they are detected automatically by the REM appveyor PushArtifact %%I.7z if defined CURL_EXE ( echo Uploading '%%I.7z' to bitbucket downloads page. echo off !CURL_EXE! !CURL_ARGS! -X POST https://api.bitbucket.org/2.0/repositories/libtcod/libtcod/downloads -F files=@"%%I.7z" @IF "!CI!" NEQ "True" echo on ) ) ) cd "!BUILD_PATH!" goto:eof REM return REM --- FUNCTION: user_function_teardown ------------------------------------- :user_function_teardown REM description: This is called just before a non-error exit. goto internal_function_exit_clean REM --- FUNCTION: internal_function_setup ------------------------------------ :internal_function_setup REM Ensure that we have a properly set up developer console with access to things like msbuild and devenv. if "%BYPASS_VS_CHECK%" NEQ "yes" ( REM Ensure that we have a properly set up developer console with access to things like msbuild and devenv. if "%VS150COMNTOOLS%" NEQ "" ( echo Your console window has already run the setup for Visual Studio %VisualStudioVersion%. echo Open a fresh window and run this script there. It will run the correct setup. pause & exit /b ) set L_VSPATH= if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" ( for /F "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -version 15 -property installationPath`) do ( set "L_VSPATH=%%i\Common7\Tools\VsDevCmd.bat" ) ) else ( set "L_VSPATH=C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat" ) CALL "!L_VSPATH!" -no_logo ) REM The top-level directory. set BUILD_SCRIPT_PATH=%~dp0 set BUILD_SCRIPT_FILENAME=%~nx0 REM The build sub-directory. set BUILD_DIRNAME=build set BUILD_PATH=%BUILD_SCRIPT_PATH%%BUILD_DIRNAME% REM The dependencies sub-directory. set DEPENDENCY_DIRNAME=%BUILD_DIRNAME%\dependencies set DEPENDENCY_PATH=%BUILD_SCRIPT_PATH%%DEPENDENCY_DIRNAME% REM Allow the user to specify the path to their Mercurial 'hg' executable. It may have to be accessed via absolute path. if not defined HG_EXE ( hg.exe >nul 2>&1 && (set HG_EXE=hg.exe) || (set HG_EXE=) ) REM Allow the user to specify the path to their Git 'git' executable. It may have to be accessed via absolute path. if not defined GIT_EXE ( REM This doesn't work directly, like hg.exe, so need where. where git.exe >nul 2>&1 && (set GIT_EXE=git.exe) || (set GIT_EXE=) ) REM If curl is present, which it should be on appveyor, then double check so it can be used for artifact uploads. if not defined CURL_EXE ( REM This doesn't work directly, like hg.exe, so need where. where curl.exe >nul 2>&1 && (set CURL_EXE=curl.exe) || (set CURL_EXE=) ) REM Allow the user to specify the path to their 7zip '7z' executable. It may have to be accessed via absolute path. if not defined 7Z_EXE ( 7z.exe >nul 2>&1 && (set 7Z_EXE=7z.exe) || (set 7Z_EXE=) if "!7Z_EXE!" EQU "" ( if exist "c:\Program Files\7-Zip\7z.exe" set 7Z_EXE="c:\Program Files\7-Zip\7z.exe" ) ) if not exist "%DEPENDENCY_PATH%" mkdir "%DEPENDENCY_PATH%" cd "%DEPENDENCY_PATH%" REM These variables are used to index the LINKS array entries. REM REM 0 1 2 3 4 5 REM HTTP link: HTTP REM VCS link: VCS REM ............ Attempt 1: Identify presence of hg.exe or git.exe, and clone or pull REM ............ Attempt 2: Download .zip as a normal link. set LINK_CLASSIFIER=0 set HTTP_URL=1 set HTTP_NAME=2 set HTTP_FILENAME=3 set VCS_SYSTEM=1 set VCS_NAME=2 set VCS_REVISION=3 set VCS_CLONEURL=4 set VCS_ZIPDLURL=5 call :user_function_setup REM --- FUNCTION: internal_function_main ------------------------------------- REM input argument: V_LINKS - The user defined links. if "%1" EQU "" ( echo Usage: !BUILD_SCRIPT_FILENAME! [OPTION] echo. echo -fd, fetch-dependencies download if necessary echo -pd, prepare-dependencies extract and/or build, ready for project build echo -mr, make-release construct release directory for packaging echo -pr, package-release compress and archive release directory echo. echo -d, dependencies fetch and prepare the dependencies echo -p, project build this project using the dependencies echo -r, release construct/compress/archive built project echo. if not defined HG_EXE ( echo WARNING: 'hg.exe' cannot be located. Mercurial may not be installed. echo This script can operate without it, but that mode is less supported. echo If Mercurial is not in PATH, you can set HG_EXE to full filename of 'hg.exe' echo. ) if not defined GIT_EXE ( echo WARNING: 'git.exe' cannot be located. Git may not be installed. echo This script can operate without it, but that mode is less supported. echo If Git is not in PATH, you can set GIT_EXE to full filename of 'git.exe' echo. ) goto internal_function_teardown ) set V_COMMANDS[fetch-dependencies]=fetch-dependencies set V_COMMANDS[prepare-dependencies]=prepare-dependencies set V_COMMANDS[make-release]=make-release set V_COMMANDS[package-release]=package-release set V_COMMANDS[dependencies]=dependencies set V_COMMANDS[project]=project set V_COMMANDS[release]=release set V_COMMANDS[-fd]=fetch-dependencies set V_COMMANDS[-pd]=prepare-dependencies set V_COMMANDS[-mr]=make-release set V_COMMANDS[-pr]=package-release set V_COMMANDS[-d]=dependencies set V_COMMANDS[-p]=project set V_COMMANDS[-r]=release :parse_args if "%~1" EQU "" goto parse_args_end set L_COMMAND=!V_COMMANDS[%~1]! if "!L_COMMAND!" EQU "" ( echo !BUILD_SCRIPT_FILENAME!: command %1 unrecognised. echo. echo Type '!BUILD_SCRIPT_FILENAME!' to see valid options. goto internal_function_teardown ) set V_COMMAND[!L_COMMAND!]=yes shift goto parse_args :parse_args_end REM Ensure sub-steps are selected for the more general commands. if "!V_COMMAND[dependencies]!" EQU "yes" ( set V_COMMAND[fetch-dependencies]=yes set V_COMMAND[prepare-dependencies]=yes ) if "!V_COMMAND[release]!" EQU "yes" ( set V_COMMAND[make-release]=yes set V_COMMAND[package-release]=yes ) if "!V_COMMAND[project]!" EQU "yes" ( set V_COMMAND[build-project]=yes ) REM Do the selected general commands. if "!V_COMMAND[fetch-dependencies]!" EQU "yes" ( call :internal_function_fetch_dependencies ) if "!V_COMMAND[prepare-dependencies]!" EQU "yes" ( call :internal_function_prepare_dependencies ) if "!V_COMMAND[build-project]!" EQU "yes" ( call :internal_function_build_project ) if "!V_COMMAND[make-release]!" EQU "yes" ( call :internal_function_make_release ) if "!V_COMMAND[package-release]!" EQU "yes" ( call :internal_function_package_release ) goto internal_function_teardown REM --- FUNCTION: internal_function_build_project ---------------------------- :internal_function_build_project cd "!BUILD_PATH!" call :user_function_build_project goto:eof REM return REM --- FUNCTION: internal_function_make_release ----------------------------- :internal_function_make_release cd "%DEPENDENCY_PATH%" call :user_function_make_release goto:eof REM return REM --- FUNCTION: internal_function_package_release -------------------------- :internal_function_package_release if "!7Z_EXE!" EQU "" ( echo ERROR: Packaging a release requires 7zip to be installed. goto internal_function_teardown ) call :user_function_package_release goto:eof REM return REM --- FUNCTION: internal_function_prepare_dependencies --------------------- :internal_function_prepare_dependencies REM input argument: V_LINKS - The user defined links. set /A IDX_PDS=0 :loop_internal_function_prepare_dependencies set V_LINK=!LINKS[%IDX_PDS%]! if "!V_LINK!" EQU "" goto loop_internal_function_prepare_dependencies_break REM function call: V_LINK_PARTS = split_link(V_LINK) call :internal_function_split_link call :internal_function_prepare_dependency set /A IDX_PDS=!IDX_PDS!+1 goto loop_internal_function_prepare_dependencies :loop_internal_function_prepare_dependencies_break call :user_function_prepare_dependencies goto:eof REM return REM --- FUNCTION: internal_function_prepare_dependency ----------------------- :internal_function_prepare_dependency REM input argument: V_LINK_PARTS - The processed link parts to make use of. REM output argument: V_LINK_PARTS - The array of elements that make up the given link text. REM 0 1 2 3 4 5 REM HTTP link: HTTP REM VCS link: VCS REM ............ Attempt 1: Identify presence of hg.exe or git.exe, and clone or pull REM ............ Attempt 2: Download .zip as a normal link. if "!V_LINK_PARTS[%LINK_CLASSIFIER%]!" EQU "https" ( REM Environment variables for function 'user_function_prepare_dependency'. set V_DIRNAME=!V_LINK_PARTS[%HTTP_FILENAME%]:~0,-4! set V_SKIPPED=no if not exist "%DEPENDENCY_PATH%\!V_DIRNAME!" ( !7Z_EXE! x %DEPENDENCY_PATH%\!V_LINK_PARTS[%HTTP_FILENAME%]! -o!V_DIRNAME! ) ) else if "!V_LINK_PARTS[%LINK_CLASSIFIER%]!" EQU "vcs" ( set V_DIRNAME=!V_LINK_PARTS[%VCS_NAME%]! REM Stop errors from nothing being here. ) call :user_function_prepare_dependency cd "%DEPENDENCY_PATH%" goto:eof REM return REM --- FUNCTION: internal_function_fetch_dependencies -------------------------- :internal_function_fetch_dependencies REM input argument: V_LINKS - The processed link parts to make use of. set /A V_IDX_FD=0 :loop_internal_function_fetch_dependencies set V_LINK=!LINKS[%V_IDX_FD%]! if "!V_LINK!" EQU "" goto exit_from_internal_function_fetch_dependencies REM function call: V_LINK_PARTS = split_link(V_LINK) call :internal_function_split_link REM function call: download_link(V_LINK_PARTS) call :internal_function_fetch_dependency set /A V_IDX_FD=!V_IDX_FD!+1 goto loop_internal_function_fetch_dependencies :exit_from_internal_function_fetch_dependencies goto:eof REM return REM --- FUNCTION: internal_function_fetch_dependency --------------------------- :internal_function_fetch_dependency REM input argument: V_LINK_PARTS - The processed link parts to make use of. REM input argument: V_IDX_FD - The index into the links array of the current dependency. REM output argument: V_LINK_PARTS - The array of elements that make up the given link text. :loop_internal_function_fetch_dependency cd "%DEPENDENCY_PATH%" if "!V_LINK_PARTS[%LINK_CLASSIFIER%]!" EQU "vcs" ( set L_VCS_DESC= if "!V_LINK_PARTS[%VCS_SYSTEM%]!" EQU "hg" ( set L_VCS_DESC=Mercurial set L_VCS_TEST_NAME=.hg set L_VCS_EXE=!HG_EXE! set L_VCS_CMD_CLONE=!HG_EXE! clone "!V_LINK_PARTS[%VCS_CLONEURL%]!" !V_LINK_PARTS[%VCS_NAME%]! set L_VCS_CMD_PULL=!HG_EXE! pull "!V_LINK_PARTS[%VCS_CLONEURL%]!" set L_VCS_CMD_UPDATE=!HG_EXE! update -r "!V_LINK_PARTS[%VCS_REVISION%]!" -C ) else if "!V_LINK_PARTS[%VCS_SYSTEM%]!" EQU "git" ( set L_VCS_DESC=Git set L_VCS_TEST_NAME=.git set L_VCS_EXE=!GIT_EXE! set L_VCS_CMD_CLONE=!GIT_EXE! clone "!V_LINK_PARTS[%VCS_CLONEURL%]!" !V_LINK_PARTS[%VCS_NAME%]! --no-checkout -b master set L_VCS_CMD_PULL=!GIT_EXE! pull "!V_LINK_PARTS[%VCS_CLONEURL%]!" set L_VCS_CMD_UPDATE=!GIT_EXE! checkout !V_LINK_PARTS[%VCS_REVISION%]! -q ) if "!L_VCS_DESC!" NEQ "" ( REM Compute whether to use the VCS system or not. if "!L_VCS_EXE!" NEQ "" ( set L_USE_VCS=yes REM Presence of directory, but lack of tested sub-directory, indicates zip archive source. if exist "!V_LINK_PARTS[%VCS_NAME%]!" ( if not exist "!V_LINK_PARTS[%VCS_NAME%]!\!L_VCS_TEST_NAME!" ( echo WARNING: While !L_VCS_DESC! is now installed, existing [!V_LINK_PARTS[%VCS_NAME%]!] directory does not use it. set L_USE_VCS=no ) ) ) else ( set L_USE_VCS=no ) if "!L_USE_VCS!" EQU "yes" ( REM Has the repository already been cloned? If so, reuse it. echo Fetching: [!V_LINK_PARTS[%VCS_NAME%]!] !L_VCS_DESC! repository. if not exist "!V_LINK_PARTS[%VCS_NAME%]!" ( REM Does not exist, fetch it. echo .. !L_VCS_CMD_CLONE! for /F "usebackq tokens=*" %%i in (`!L_VCS_CMD_CLONE!`) do ( echo .. !L_VCS_EXE!: %%i ) REM The subsequent VCS update needs to be within the repository directory. cd !V_LINK_PARTS[%VCS_NAME%]! ) else ( REM The VCS pull and subsequent update needs to be within the repository directory. echo .. !L_VCS_CMD_PULL! cd !V_LINK_PARTS[%VCS_NAME%]! for /F "usebackq tokens=*" %%i in (`!L_VCS_CMD_PULL!`) do ( echo .. !L_VCS_EXE!: %%i ) ) echo Updating: [!V_LINK_PARTS[%VCS_NAME%]!] !L_VCS_DESC! repository to revision [!V_LINK_PARTS[%VCS_REVISION%]!]. for /F "usebackq tokens=*" %%i in (`!L_VCS_CMD_UPDATE!`) do ( echo .. !L_VCS_EXE!: %%i ) goto exit_from_internal_function_fetch_dependency ) else ( if exist "!V_LINK_PARTS[%VCS_NAME%]!" ( if exist "!V_LINK_PARTS[%VCS_NAME%]!\!L_VCS_TEST_NAME!" ( echo WARNING: No !L_VCS_DESC! client installed yet [!V_LINK_PARTS[%VCS_NAME%]!] was originally created using one. echo WARNING: Therefore [!V_LINK_PARTS[%VCS_NAME%]!] cannot be updated. goto exit_from_internal_function_fetch_dependency ) ) REM Fall back to ZIP archive downloading. Ordering of these assignments is important as some overwrite others. echo WARNING: This is untested code. If it does not work, report it. set V_LINK_PARTS[%HTTP_NAME%]=!V_LINK_PARTS[%VCS_NAME%]! set V_LINK_PARTS[%LINK_CLASSIFIER%]=http echo Download of VCS repo snapshots not fully implemented, giving up. goto internal_function_exit REM TODO: Set this to !V_LINK_PARTS[%VCS_ZIPDLURL%]! with 'REV' replaced with !V_LINK_PARTS[%VCS_REVISION%]! set V_LINK_PARTS[%HTTP_URL%]=!V_LINK_PARTS[%VCS_ZIPDLURL%]! REM TODO: Set this to the extracted file name from the HTTP_URL we just constructed. set V_LINK_PARTS[%HTTP_FILENAME%]= ) ) ) REM Skip logic to keep script flat, as not possible to have label inside if statement block. if "!V_LINK_PARTS[%LINK_CLASSIFIER%]!" NEQ "https" goto exit_from_internal_function_fetch_dependency set /A L_ATTEMPTS=0 :internal_function_fetch_dependency_retry if not exist "!V_LINK_PARTS[%HTTP_NAME%]!" ( echo Downloading: [!V_LINK_PARTS[%HTTP_NAME%]!] powershell -c "Start-BitsTransfer -source !V_LINK_PARTS[%HTTP_URL%]!" if not exist !V_LINK_PARTS[%HTTP_FILENAME%]! ( echo Failed to download !V_LINK_PARTS[%HTTP_FILENAME%]! goto internal_function_exit ) ) else ( echo Downloading: [!V_LINK_PARTS[%HTTP_NAME%]!] .. skipped ) set /A L_ATTEMPTS=!L_ATTEMPTS!+1 call :internal_function_checksum if "!V_PASSED!" EQU "yes" ( echo .. MD5 checksum [!V_CHECKSUM!] correct ) else if "!V_PASSED!" EQU "no" ( echo .. MD5 checksum [!V_CHECKSUM!] incorrect echo .. Expected: [!MD5CHECKSUMS[%V_IDX_FD%]!] if !L_ATTEMPTS! EQU 1 ( set /p L_RESULT="Attempt to re-download the file [Y/n]?" if /I "!L_RESULT!" NEQ "n" ( del !V_LINK_PARTS[%HTTP_FILENAME%]! goto internal_function_fetch_dependency_retry ) ) echo ERROR: Failed to obtain valid copy of [!V_LINK_PARTS[%HTTP_FILENAME%]!] goto internal_function_exit ) else ( echo .. MD5 checksum [!V_CHECKSUM!] unknown ) :exit_from_internal_function_fetch_dependency goto:eof REM return REM --- FUNCTION: internal_function_checksum --------------------------------- :internal_function_checksum REM input argument: V_LINK_PARTS - The array of elements relating to the link in question. REM output argument: V_CHECKSUM - The calculated checksum for the given file. REM output argument: V_PASSED - If there is one to match, "yes" for correct and "no" for incorrect. REM If there is not one to match, "". set fn=MD5-Checksum set fnp0=!V_LINK_PARTS[%HTTP_FILENAME%]! set fnp1=discard set V_PASSED= REM Iterate over the lines of output. for /F "usebackq tokens=*" %%i in (`more "%BUILD_SCRIPT_PATH%%BUILD_SCRIPT_FILENAME%" ^| powershell -c -`) do ( set L_LINE=%%i if "!L_LINE:~0,4!" EQU "MSG:" ( set V_CHECKSUM=!L_LINE:~5! set L_CHECKSUM=!MD5CHECKSUMS[%V_IDX_FD%]! if "!L_CHECKSUM!" NEQ "" ( if "!L_CHECKSUM!" EQU "!V_CHECKSUM!" ( set V_PASSED=yes ) else ( set V_PASSED=no ) ) ) else ( echo Unexpected result in checksum function: !L_LINE! goto internal_function_exit ) ) :exit_from_internal_function_checksum goto:eof REM return REM --- FUNCTION: internal_function_verify_link ------------------------------ :internal_function_verify_link REM input argument: V_LINK - The link text to verify. REM output argument: V_LINK_PARTS - The array of elements that make up the given link text. REM function call: V_LINK_PARTS = split_link(V_LINK) call :internal_function_split_link if "!V_LINK_PARTS[%LINK_CLASSIFIER%]!" EQU "http" ( if /I "!V_LINK_PARTS[%HTTP_URL%]:~0,4!" NEQ "http" goto internal_function_verify_link__valid if /I "!V_LINK_PARTS[%HTTP_URL%]:~-4,4!" NEQ ".zip" goto internal_function_verify_link__valid ) else if "!V_LINK_PARTS[%LINK_CLASSIFIER%]!" EQU "vcs" ( if "!V_LINK_PARTS[%VCS_SYSTEM%]!" EQU "hg" goto internal_function_verify_link__valid ) REM emergency exit with error message. echo Invalid link: %V_LINK% goto internal_function_exit :internal_function_verify_link__valid goto:eof REM return REM --- FUNCTION: internal_function_split_link ------------------------------- :internal_function_split_link REM input argument: V_LINK - The link text to verify. REM output argument: V_LINK_PARTS - The array of elements that make up the given link text. set V_LINK_PARTS[%LINK_CLASSIFIER%]= for /F "tokens=1,2,3,4,5,6" %%A in ("!V_LINK!") do ( set L_FIRST=%%A if /I "!L_FIRST:~0,8!" EQU "https://" ( set V_LINK_PARTS[%LINK_CLASSIFIER%]=https set V_LINK_PARTS[%HTTP_URL%]=!V_LINK! REM .. V_LINK_PARTS[%HTTP_NAME%], V_LINK_PARTS[%HTTP_FILENAME%] = get_urlfilename(V_LINK) call :internal_function_get_urlfilename set V_LINK_PARTS[%HTTP_NAME%]=!V_RESULT! set V_LINK_PARTS[%HTTP_FILENAME%]=!V_RESULT! ) else ( set V_LINK_PARTS[%LINK_CLASSIFIER%]=%%A set V_LINK_PARTS[%VCS_SYSTEM%]=%%B set V_LINK_PARTS[%VCS_NAME%]=%%C set V_LINK_PARTS[%VCS_REVISION%]=%%D set V_LINK_PARTS[%VCS_CLONEURL%]=%%E set V_LINK_PARTS[%VCS_ZIPDLURL%]=%%F ) ) :exit_from_internal_function_split_link goto:eof REM return REM --- FUNCTION: internal_function_get_urlfilename --------------------------- :internal_function_get_urlfilename REM input argument: V_LINK - The link text to verify. REM output argument: V_RESULT - The base filename the URL exposes for download. set L_LINK=!V_LINK! :loop_internal_function_get_urlfilename_1 if "!L_LINK!" EQU "" goto loop0continue REM Select the substring up to the first path separator. for /f "delims=/" %%M in ("!L_LINK!") do set L_SUBSTRING=%%M :loop_internal_function_get_urlfilename_2 REM Skip until the next path separator. set L_CHAR=!L_LINK:~0,1! set L_LINK=!L_LINK:~1! if "!L_LINK!" EQU "" goto loop_internal_function_get_urlfilename_3 if "!L_CHAR!" NEQ "/" goto loop_internal_function_get_urlfilename_2 goto loop_internal_function_get_urlfilename_1 :loop_internal_function_get_urlfilename_3 REM We have the trailing string after the last path separator, or the file name. set V_RESULT=!L_SUBSTRING! goto:eof REM return REM --- FUNCTION: internal_function_get_date --------------------------------- :internal_function_get_date REM output argument: V_RESULT - The date in form YYYYMMDD FOR /F "tokens=3" %%A IN ('REG QUERY "HKCU\Control Panel\International" /v sShortDate 2^>NUL') DO ( SET sShortDate=%%A ) for /f "tokens=2-4 delims=/ " %%a in ('date /t') do ( if "!sShortDate:~0,1!" EQU "d" ( set V_RESULT=%%c%%b%%a ) else ( set V_RESULT=%%c%%a%%b ) ) goto:eof REM return REM --- Everything is done, exit back to the user ---------------------------- :internal_function_teardown REM Now that processing is done, allow the user to do some steps before exiting. set EXIT_CODE=0 goto user_function_teardown :internal_function_exit set EXIT_CODE=1 :internal_function_exit_clean REM Leave the user in the directory they were in to begin with. cd %BUILD_SCRIPT_PATH% REM endlocal: Ensure environment variables are left the same as when the script started. REM exit /b: Exit the script, but do not close any DOS window it was run from within. endlocal & exit /b !EXIT_CODE! #> function MD5-Checksum([string]$path, [string]$discard) { # $fullPath = Resolve-Path $path; $md5 = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider; $file = [System.IO.File]::Open($path, [System.IO.Filemode]::Open, [System.IO.FileAccess]::Read); $hash = [System.BitConverter]::ToString($md5.ComputeHash($file)) Write-Host "MSG: $hash"; $file.Dispose(); return 0; } function Archive-Extract([string]$zipFilePath, [string]$destinationPath) { # This will get added when paths are joined, and path comparison will need it to be absent. $destinationPath = $destinationPath.TrimEnd("\"); [Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem') > $null; $zipfile = [IO.Compression.ZipFile]::OpenRead($zipFilePath); # Determine how many top level entries there are. $ziplevel0files = @{}; $zipfile.Entries | foreach { $s = ($_.FullName.TrimEnd("/") -split "/")[0]; if ($ziplevel0files.ContainsKey($s)) { $ziplevel0files[$s] = $ziplevel0files[$s] + 1; } else { $ziplevel0files[$s] = 0; } } if ($ziplevel0files.count -ne 1) { $zipDirName = [io.path]::GetFileNameWithoutExtension($zipFilePath) $zipDirPath = $destinationPath = Join-Path -Path $destinationPath -ChildPath $zipDirName } else { $zipDirName = $ziplevel0files.Keys[0] $zipDirPath = Join-Path -Path $destinationPath -ChildPath $zipDirName; } Write-Host "EXTRACTPATH: $zipDirName"; if (Test-Path -LiteralPath $zipDirPath) { Write-Host "MSG: EXTRACTED"; return 2; # Failure } Write-Host "MSG: EXTRACTING"; $zipfile.Entries | foreach { $extractFilePath = Join-Path -Path $destinationPath -ChildPath $_.FullName; $extractFileDirPath = Split-Path -Parent $extractFilePath; if (-not (Test-Path -LiteralPath $extractFileDirPath -PathType Container)) { New-Item -Path $extractFileDirPath -Type Directory | Out-Null; } # Sometimes a directory comes after a file within the directory (the latter causes it to be created implicitly above). if (-not $extractFilePath.EndsWith("\")) { try { [IO.Compression.ZipFileExtensions]::ExtractToFile($_, $extractFilePath, $true); } catch { Write-Host "MSG: Failed to extract file:" $extractFilePath; return 3; # Failure } } } return 0; # Success } # Anything that calls should execute the powershell and set the parameters. $fn = (Get-ChildItem Env:fn).Value; $arg0 = (Get-ChildItem Env:fnp0).Value; $arg1 = (Get-ChildItem Env:fnp1).Value; $err = & $fn $arg0 $arg1; exit $err; libtcod-1.6.4+dfsg/build/000077500000000000000000000000001321276576200151735ustar00rootroot00000000000000libtcod-1.6.4+dfsg/build/README.txt000066400000000000000000000000361321276576200166700ustar00rootroot00000000000000See the top-level README file.libtcod-1.6.4+dfsg/build/autotools/000077500000000000000000000000001321276576200172245ustar00rootroot00000000000000libtcod-1.6.4+dfsg/build/autotools/Makefile.am000066400000000000000000000160231321276576200212620ustar00rootroot00000000000000ACLOCAL_AMFLAGS = -I m4 AM_CFLAGS = \ -I$(top_srcdir)/../../include \ -DTCOD_SDL2 -DNO_OPENGL \ -DNDEBUG -O2 \ $(SDL_CFLAGS) $(X11_CFLAGS) $(ZLIB_CFLAGS) AM_CPPFLAGS = $(AM_CFLAGS) AM_LDFLAGS = $(SDL_LIBS) $(X11_LIBS) $(ZLIB_LIBS) lib_LTLIBRARIES = libtcod.la libtcodxx.la libtcodgui.la libtcodgui_la_SOURCES = \ ../../src/gui/button.cpp \ ../../src/gui/container.cpp \ ../../src/gui/flatlist.cpp \ ../../src/gui/hbox.cpp \ ../../src/gui/image.cpp \ ../../src/gui/label.cpp \ ../../src/gui/radiobutton.cpp \ ../../src/gui/slider.cpp \ ../../src/gui/statusbar.cpp \ ../../src/gui/textbox.cpp \ ../../src/gui/togglebutton.cpp \ ../../src/gui/toolbar.cpp \ ../../src/gui/vbox.cpp \ ../../src/gui/widget.cpp libtcodgui_la_CXXFLAGS = $(CXXFLAGS) -I$(top_srcdir)/../../include/gui libtcodgui_la_LIBADD = libtcodxx.la libtcod.la otherincludedir = $(includedir)/libtcod/gui otherinclude_HEADERS = \ ../../include/gui/button.hpp \ ../../include/gui/container.hpp \ ../../include/gui/flatlist.hpp \ ../../include/gui/gui.hpp \ ../../include/gui/hbox.hpp \ ../../include/gui/image.hpp \ ../../include/gui/label.hpp \ ../../include/gui/radiobutton.hpp \ ../../include/gui/slider.hpp \ ../../include/gui/statusbar.hpp \ ../../include/gui/textbox.hpp \ ../../include/gui/togglebutton.hpp \ ../../include/gui/toolbar.hpp \ ../../include/gui/vbox.hpp \ ../../include/gui/widget.hpp libtcod_la_SOURCES = \ ../../src/bresenham_c.c \ ../../src/bsp_c.c \ ../../src/color_c.c \ ../../src/console_c.c \ ../../src/console_rexpaint.c \ ../../src/fov_c.c \ ../../src/fov_circular_raycasting.c \ ../../src/fov_diamond_raycasting.c \ ../../src/fov_permissive2.c \ ../../src/fov_recursive_shadowcasting.c \ ../../src/fov_restrictive.c \ ../../src/heightmap_c.c \ ../../src/image_c.c \ ../../src/lex_c.c \ ../../src/list_c.c \ ../../src/mersenne_c.c \ ../../src/namegen_c.c \ ../../src/noise_c.c \ ../../src/parser_c.c \ ../../src/path_c.c \ ../../src/sys_c.c \ ../../src/sys_sdl2_c.c \ ../../src/sys_sdl_c.c \ ../../src/sys_sdl_img_bmp.c \ ../../src/sys_sdl_img_png.c \ ../../src/tree_c.c \ ../../src/txtfield_c.c \ ../../src/wrappers.c \ ../../src/zip_c.c \ ../../src/png/lodepng.c \ ../../src/png/lodepng.h libtcod_la_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) libtcod_la_LIBADD = $(PTHREAD_LIBS) pkginclude_HEADERS = \ ../../include/bresenham.h \ ../../include/mersenne_types.h \ ../../include/bsp.h \ ../../include/mouse.h \ ../../include/color.h \ ../../include/mouse_types.h \ ../../include/console.h \ ../../include/namegen.h \ ../../include/console_types.h \ ../../include/noise_defaults.h \ ../../include/fov.h \ ../../include/noise.h \ ../../include/fov_types.h \ ../../include/parser.h \ ../../include/heightmap.h \ ../../include/path.h \ ../../include/image.h \ ../../include/sys.h \ ../../include/lex.h \ ../../include/tree.h \ ../../include/libtcod.h \ ../../include/txtfield.h \ ../../include/libtcod_int.h \ ../../include/libtcod_portability.h \ ../../include/libtcod_utility.h \ ../../include/libtcod_version.h \ ../../include/wrappers.h \ ../../include/list.h \ ../../include/zip.h \ ../../include/mersenne.h \ ../../include/external/pstdint.h \ ../../include/bresenham.hpp \ ../../include/mersenne.hpp \ ../../include/bsp.hpp \ ../../include/mouse.hpp \ ../../include/color.hpp \ ../../include/namegen.hpp \ ../../include/console.hpp \ ../../include/noise.hpp \ ../../include/fov.hpp \ ../../include/parser.hpp \ ../../include/heightmap.hpp \ ../../include/path.hpp \ ../../include/howto.hpp \ ../../include/sys.hpp \ ../../include/image.hpp \ ../../include/tree.hpp \ ../../include/lex.hpp \ ../../include/txtfield.hpp \ ../../include/libtcod.hpp \ ../../include/zip.hpp \ ../../include/list.hpp libtcodxx_la_SOURCES = \ ../../src/bresenham.cpp \ ../../src/bsp.cpp \ ../../src/color.cpp \ ../../src/console.cpp \ ../../src/fov.cpp \ ../../src/heightmap.cpp \ ../../src/image.cpp \ ../../src/lex.cpp \ ../../src/mersenne.cpp \ ../../src/mouse.cpp \ ../../src/namegen.cpp \ ../../src/noise.cpp \ ../../src/parser.cpp \ ../../src/path.cpp \ ../../src/sys.cpp \ ../../src/txtfield.cpp \ ../../src/zip.cpp libtcodxx_la_LIBADD = libtcod.la if ENABLE_SAMPLES noinst_PROGRAMS = samples_c samples_cpp samples_c_SOURCES = ../../samples/samples_c.c samples_c_LDADD = libtcod.la samples_cpp_SOURCES = ../../samples/samples_cpp.cpp samples_cpp_LDADD = libtcodxx.la libtcod.la endif dist_noinst_DATA = \ ../../build.bat ../../libtcod-CHANGELOG.txt \ ../../LIBTCOD-CREDITS.txt \ ../../LIBTCOD-LICENSE.txt \ ../../README-linux-SDL2.txt \ ../../README.md \ ../../libtcod.cfg dist_noinst_DATA += \ ../../terminal.png \ ../../data/img/circle.png \ ../../data/img/skull.png \ ../../data/namegen/mingos_town.cfg \ ../../data/namegen/README.txt \ ../../data/namegen/mingos_demon.cfg \ ../../data/namegen/mingos_dwarf.cfg \ ../../data/namegen/jice_norse.cfg \ ../../data/namegen/jice_town.cfg \ ../../data/namegen/jice_region.cfg \ ../../data/namegen/jice_celtic.cfg \ ../../data/namegen/mingos_norse.cfg \ ../../data/namegen/jice_fantasy.cfg \ ../../data/namegen/mingos_standard.cfg \ ../../data/namegen/jice_mesopotamian.cfg \ ../../data/fonts/dejavu8x8_gs_tc.png \ ../../data/fonts/consolas10x10_gs_tc.png \ ../../data/fonts/dundalk12x12_gs_tc.png \ ../../data/fonts/terminal8x8_gs_as.png \ ../../data/fonts/README.txt \ ../../data/fonts/terminal8x12_gs_tc.png \ ../../data/fonts/courier12x12_aa_tc.png \ ../../data/fonts/arial10x10.png \ ../../data/fonts/prestige12x12_gs_tc.png \ ../../data/fonts/terminal8x8_aa_as.png \ ../../data/fonts/terminal8x14_gs_ro.png \ ../../data/fonts/terminal8x12_gs_ro.png \ ../../data/fonts/terminal16x16_gs_ro.png \ ../../data/fonts/prestige10x10_gs_tc.png \ ../../data/fonts/caeldera8x8_gs_tc.png \ ../../data/fonts/terminal7x7_gs_tc.png \ ../../data/fonts/terminal10x18_gs_ro.png \ ../../data/fonts/terminal10x16_gs_tc.png \ ../../data/fonts/dejavu_wide12x12_gs_tc.png \ ../../data/fonts/consolas_unicode_8x8.png \ ../../data/fonts/arial8x8.png \ ../../data/fonts/terminal8x8_gs_tc.png \ ../../data/fonts/dejavu12x12_gs_tc.png \ ../../data/fonts/consolas_unicode_12x12.png \ ../../data/fonts/lucida12x12_gs_tc.png \ ../../data/fonts/arial12x12.png \ ../../data/fonts/consolas8x8_gs_tc.png \ ../../data/fonts/consolas_unicode_16x16.png \ ../../data/fonts/lucida8x8_gs_tc.png \ ../../data/fonts/terminal10x16_gs_ro.png \ ../../data/fonts/dejavu_wide16x16_gs_tc.png \ ../../data/fonts/consolas12x12_gs_tc.png \ ../../data/fonts/terminal8x8_aa_ro.png \ ../../data/fonts/terminal10x10_gs_tc.png \ ../../data/fonts/prestige8x8_gs_tc.png \ ../../data/fonts/terminal8x8_aa_tc.png \ ../../data/fonts/terminal12x12_gs_ro.png \ ../../data/fonts/celtic_garamond_10x10_gs_tc.png \ ../../data/fonts/courier8x8_aa_tc.png \ ../../data/fonts/lucida10x10_gs_tc.png \ ../../data/fonts/consolas_unicode_10x10.png \ ../../data/fonts/courier10x10_aa_tc.png \ ../../data/fonts/terminal8x8_gs_ro.png \ ../../data/fonts/dejavu16x16_gs_tc.png \ ../../data/fonts/dejavu10x10_gs_tc.png libtcod-1.6.4+dfsg/build/autotools/configure.ac000066400000000000000000000025761321276576200215240ustar00rootroot00000000000000AC_INIT([libtcod], [1.6]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_AUX_DIR([build-aux]) AC_CANONICAL_HOST AM_INIT_AUTOMAKE([1.14 subdir-objects foreign]) AM_SILENT_RULES([yes]) AM_MAINTAINER_MODE([enable]) LT_INIT AC_PROG_CC AC_PROG_CXX AC_PROG_INSTALL AM_PROG_CC_C_O AC_ARG_ENABLE([samples], [AS_HELP_STRING([--enable-samples], [enable building sample applications])]) AM_CONDITIONAL([ENABLE_SAMPLES], [test "x${enable_samples}" != "xno"]) dnl ----------------------------------- dnl From wiki.libsdl.org/FAQLinux dnl Check for SDL2 SDL_VERSION=2.0.0 AM_PATH_SDL2($SDL_VERSION, :, AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!])) dnl ----------------------------------- AC_CHECK_HEADERS([stdlib.h math.h stdio.h stdarg.h string.h stdlib.h ctype.h wchar.h wctype.h time.h sys/stat.h X11/Xlib.h X11/Xatom.h unistd.h sys/types.h dirent.h errno.h pthread.h semaphore.h dlfcn.h]) AC_SEARCH_LIBS([atan2], [m], [:], [AC_MSG_ERROR([can't find the maths library])]) PKG_CHECK_MODULES([ZLIB], [zlib >= 1.2.0]) AS_CASE([$host_os], [mingw*], [:], [darwin*], [:], [linux-android*], [:], [haiku*], [:], [PKG_CHECK_MODULES([X11], [x11 >= 1.6.0])] ) AS_CASE([$host_os], [mingw*], [:], [ AC_SEARCH_LIBS([dlopen], [dl], [:], [AC_MSG_ERROR([can't find dlopen])]) AX_PTHREAD([:], [AC_MSG_ERROR([can't find pthreads])]) ] ) AC_CONFIG_FILES([Makefile]) AC_OUTPUT libtcod-1.6.4+dfsg/build/autotools/m4/000077500000000000000000000000001321276576200175445ustar00rootroot00000000000000libtcod-1.6.4+dfsg/build/autotools/m4/am_path_sdl2.m4000066400000000000000000000155301321276576200223470ustar00rootroot00000000000000dnl Configure paths for SDL dnl Sam Lantinga 9/21/99 dnl stolen from Manish Singh dnl stolen back from Frank Belew dnl stolen from Manish Singh dnl Shamelessly stolen from Owen Taylor dnl dnl serial 1 dnl dnl AM_PATH_SDL2([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS dnl AC_DEFUN([AM_PATH_SDL2], [dnl dnl Get the cflags and libraries from the sdl2-config script dnl AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)], sdl_prefix="$withval", sdl_prefix="") AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)], sdl_exec_prefix="$withval", sdl_exec_prefix="") AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program], , enable_sdltest=yes) min_sdl_version=ifelse([$1], ,2.0.0,$1) if test "x$sdl_prefix$sdl_exec_prefix" = x ; then PKG_CHECK_MODULES([SDL], [sdl2 >= $min_sdl_version], [sdl_pc=yes], [sdl_pc=no]) else sdl_pc=no if test x$sdl_exec_prefix != x ; then sdl_config_args="$sdl_config_args --exec-prefix=$sdl_exec_prefix" if test x${SDL2_CONFIG+set} != xset ; then SDL2_CONFIG=$sdl_exec_prefix/bin/sdl2-config fi fi if test x$sdl_prefix != x ; then sdl_config_args="$sdl_config_args --prefix=$sdl_prefix" if test x${SDL2_CONFIG+set} != xset ; then SDL2_CONFIG=$sdl_prefix/bin/sdl2-config fi fi fi if test "x$sdl_pc" = xyes ; then no_sdl="" SDL2_CONFIG="pkg-config sdl2" else as_save_PATH="$PATH" if test "x$prefix" != xNONE && test "$cross_compiling" != yes; then PATH="$prefix/bin:$prefix/usr/bin:$PATH" fi AC_PATH_PROG(SDL2_CONFIG, sdl2-config, no, [$PATH]) PATH="$as_save_PATH" AC_MSG_CHECKING(for SDL - version >= $min_sdl_version) no_sdl="" if test "$SDL2_CONFIG" = "no" ; then no_sdl=yes else SDL_CFLAGS=`$SDL2_CONFIG $sdl_config_args --cflags` SDL_LIBS=`$SDL2_CONFIG $sdl_config_args --libs` sdl_major_version=`$SDL2_CONFIG $sdl_config_args --version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` sdl_minor_version=`$SDL2_CONFIG $sdl_config_args --version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` sdl_micro_version=`$SDL2_CONFIG $sdl_config_args --version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` if test "x$enable_sdltest" = "xyes" ; then ac_save_CFLAGS="$CFLAGS" ac_save_CXXFLAGS="$CXXFLAGS" ac_save_LIBS="$LIBS" CFLAGS="$CFLAGS $SDL_CFLAGS" CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" LIBS="$LIBS $SDL_LIBS" dnl dnl Now check if the installed SDL is sufficiently new. (Also sanity dnl checks the results of sdl2-config to some extent dnl rm -f conf.sdltest AC_TRY_RUN([ #include #include #include #include "SDL.h" char* my_strdup (char *str) { char *new_str; if (str) { new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char)); strcpy (new_str, str); } else new_str = NULL; return new_str; } int main (int argc, char *argv[]) { int major, minor, micro; char *tmp_version; /* This hangs on some systems (?) system ("touch conf.sdltest"); */ { FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); } /* HP/UX 9 (%@#!) writes to sscanf strings */ tmp_version = my_strdup("$min_sdl_version"); if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { printf("%s, bad version string\n", "$min_sdl_version"); exit(1); } if (($sdl_major_version > major) || (($sdl_major_version == major) && ($sdl_minor_version > minor)) || (($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro))) { return 0; } else { printf("\n*** 'sdl2-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version); printf("*** of SDL required is %d.%d.%d. If sdl2-config is correct, then it is\n", major, minor, micro); printf("*** best to upgrade to the required version.\n"); printf("*** If sdl2-config was wrong, set the environment variable SDL2_CONFIG\n"); printf("*** to point to the correct copy of sdl2-config, and remove the file\n"); printf("*** config.cache before re-running configure\n"); return 1; } } ],, no_sdl=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) CFLAGS="$ac_save_CFLAGS" CXXFLAGS="$ac_save_CXXFLAGS" LIBS="$ac_save_LIBS" fi fi if test "x$no_sdl" = x ; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi fi if test "x$no_sdl" = x ; then ifelse([$2], , :, [$2]) else if test "$SDL2_CONFIG" = "no" ; then echo "*** The sdl2-config script installed by SDL could not be found" echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in" echo "*** your path, or set the SDL2_CONFIG environment variable to the" echo "*** full path to sdl2-config." else if test -f conf.sdltest ; then : else echo "*** Could not run SDL test program, checking why..." CFLAGS="$CFLAGS $SDL_CFLAGS" CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" LIBS="$LIBS $SDL_LIBS" AC_TRY_LINK([ #include #include "SDL.h" int main(int argc, char *argv[]) { return 0; } #undef main #define main K_and_R_C_main ], [ return 0; ], [ echo "*** The test program compiled, but did not run. This usually means" echo "*** that the run-time linker is not finding SDL or finding the wrong" echo "*** version of SDL. If it is not finding SDL, you'll need to set your" echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" echo "*** to the installed location Also, make sure you have run ldconfig if that" echo "*** is required on your system" echo "***" echo "*** If you have an old version installed, it is best to remove it, although" echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], [ echo "*** The test program failed to compile or link. See the file config.log for the" echo "*** exact error that occurred. This usually means SDL was incorrectly installed" echo "*** or that you have moved SDL since it was installed. In the latter case, you" echo "*** may want to edit the sdl2-config script: $SDL2_CONFIG" ]) CFLAGS="$ac_save_CFLAGS" CXXFLAGS="$ac_save_CXXFLAGS" LIBS="$ac_save_LIBS" fi fi SDL_CFLAGS="" SDL_LIBS="" ifelse([$3], , :, [$3]) fi AC_SUBST(SDL_CFLAGS) AC_SUBST(SDL_LIBS) rm -f conf.sdltest ]) libtcod-1.6.4+dfsg/build/autotools/m4/ax_pthread.m4000066400000000000000000000505201321276576200221270ustar00rootroot00000000000000# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_pthread.html # =========================================================================== # # SYNOPSIS # # AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) # # DESCRIPTION # # This macro figures out how to build C programs using POSIX threads. It # sets the PTHREAD_LIBS output variable to the threads library and linker # flags, and the PTHREAD_CFLAGS output variable to any special C compiler # flags that are needed. (The user can also force certain compiler # flags/libs to be tested by setting these environment variables.) # # Also sets PTHREAD_CC to any special C compiler that is needed for # multi-threaded programs (defaults to the value of CC otherwise). (This # is necessary on AIX to use the special cc_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these flags, # but also to link with them as well. For example, you might link with # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # # If you are only building threaded programs, you may wish to use these # variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" # CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # CC="$PTHREAD_CC" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant # has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to # that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). # # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the # PTHREAD_PRIO_INHERIT symbol is defined when compiling with # PTHREAD_CFLAGS. # # ACTION-IF-FOUND is a list of shell commands to run if a threads library # is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it # is not found. If ACTION-IF-FOUND is not specified, the default action # will define HAVE_PTHREAD. # # Please let the authors know if this macro fails on any platform, or if # you have any other suggestions or comments. This macro was based on work # by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help # from M. Frigo), as well as ac_pthread and hb_pthread macros posted by # Alejandro Forero Cuervo to the autoconf macro repository. We are also # grateful for the helpful feedback of numerous users. # # Updated for Autoconf 2.68 by Daniel Richard G. # # LICENSE # # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2011 Daniel Richard G. # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 23 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_PROG_SED]) AC_LANG_PUSH([C]) ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on Tru64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then ax_pthread_save_CC="$CC" ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) AC_MSG_RESULT([$ax_pthread_ok]) if test "x$ax_pthread_ok" = "xno"; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi CC="$ax_pthread_save_CC" CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 # (Note: HP C rejects this with "bad form for `-t' option") # -pthreads: Solaris/gcc (Note: HP C also rejects) # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads and # -D_REENTRANT too), HP C (must be checked before -lpthread, which # is present but should not be used directly; and before -mthreads, # because the compiler interprets this as "-mt" + "-hreads") # -mthreads: Mingw32/gcc, Lynx/gcc # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case $host_os in freebsd*) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) ax_pthread_flags="-kthread lthread $ax_pthread_flags" ;; hpux*) # From the cc(1) man page: "[-mt] Sets various -D flags to enable # multi-threading and also sets -lpthread." ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" ;; openedition*) # IBM z/OS requires a feature-test macro to be defined in order to # enable POSIX threads at all, so give the user a hint if this is # not set. (We don't define these ourselves, as they can affect # other portions of the system API in unpredictable ways.) AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], [ # if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) AX_PTHREAD_ZOS_MISSING # endif ], [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) ;; solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (N.B.: The stubs are missing # pthread_cleanup_push, or rather a function called by this macro, # so we could check for that, but who knows whether they'll stub # that too in a future libc.) So we'll check first for the # standard Solaris way of linking pthreads (-mt -lpthread). ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" ;; esac # GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) AS_IF([test "x$GCC" = "xyes"], [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"]) # The presence of a feature test macro requesting re-entrant function # definitions is, on some systems, a strong hint that pthreads support is # correctly enabled case $host_os in darwin* | hpux* | linux* | osf* | solaris*) ax_pthread_check_macro="_REENTRANT" ;; aix*) ax_pthread_check_macro="_THREAD_SAFE" ;; *) ax_pthread_check_macro="--" ;; esac AS_IF([test "x$ax_pthread_check_macro" = "x--"], [ax_pthread_check_cond=0], [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) # Are we compiling with Clang? AC_CACHE_CHECK([whether $CC is Clang], [ax_cv_PTHREAD_CLANG], [ax_cv_PTHREAD_CLANG=no # Note that Autoconf sets GCC=yes for Clang as well as GCC if test "x$GCC" = "xyes"; then AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ # if defined(__clang__) && defined(__llvm__) AX_PTHREAD_CC_IS_CLANG # endif ], [ax_cv_PTHREAD_CLANG=yes]) fi ]) ax_pthread_clang="$ax_cv_PTHREAD_CLANG" ax_pthread_clang_warning=no # Clang needs special handling, because older versions handle the -pthread # option in a rather... idiosyncratic way if test "x$ax_pthread_clang" = "xyes"; then # Clang takes -pthread; it has never supported any other flag # (Note 1: This will need to be revisited if a system that Clang # supports has POSIX threads in a separate library. This tends not # to be the way of modern systems, but it's conceivable.) # (Note 2: On some systems, notably Darwin, -pthread is not needed # to get POSIX threads support; the API is always present and # active. We could reasonably leave PTHREAD_CFLAGS empty. But # -pthread does define _REENTRANT, and while the Darwin headers # ignore this macro, third-party headers might not.) PTHREAD_CFLAGS="-pthread" PTHREAD_LIBS= ax_pthread_ok=yes # However, older versions of Clang make a point of warning the user # that, in an invocation where only linking and no compilation is # taking place, the -pthread option has no effect ("argument unused # during compilation"). They expect -pthread to be passed in only # when source code is being compiled. # # Problem is, this is at odds with the way Automake and most other # C build frameworks function, which is that the same flags used in # compilation (CFLAGS) are also used in linking. Many systems # supported by AX_PTHREAD require exactly this for POSIX threads # support, and in fact it is often not straightforward to specify a # flag that is used only in the compilation phase and not in # linking. Such a scenario is extremely rare in practice. # # Even though use of the -pthread flag in linking would only print # a warning, this can be a nuisance for well-run software projects # that build with -Werror. So if the active version of Clang has # this misfeature, we search for an option to squash it. AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown # Create an alternate version of $ac_link that compiles and # links in two steps (.c -> .o, .o -> exe) instead of one # (.c -> exe), because the warning occurs only in the second # step ax_pthread_save_ac_link="$ac_link" ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" ax_pthread_save_CFLAGS="$CFLAGS" for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" ac_link="$ax_pthread_save_ac_link" AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], [ac_link="$ax_pthread_2step_ac_link" AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], [break]) ]) done ac_link="$ax_pthread_save_ac_link" CFLAGS="$ax_pthread_save_CFLAGS" AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" ]) case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in no | unknown) ;; *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; esac fi # $ax_pthread_clang = yes if test "x$ax_pthread_ok" = "xno"; then for ax_pthread_try_flag in $ax_pthread_flags; do case $ax_pthread_try_flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; -mt,pthread) AC_MSG_CHECKING([whether pthreads work with -mt -lpthread]) PTHREAD_CFLAGS="-mt" PTHREAD_LIBS="-lpthread" ;; -*) AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) PTHREAD_CFLAGS="$ax_pthread_try_flag" ;; pthread-config) AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) PTHREAD_LIBS="-l$ax_pthread_try_flag" ;; esac ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. AC_LINK_IFELSE([AC_LANG_PROGRAM([#include # if $ax_pthread_check_cond # error "$ax_pthread_check_macro must be defined" # endif static void routine(void *a) { a = 0; } static void *start_routine(void *a) { return a; }], [pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); pthread_join(th, 0); pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_cleanup_pop(0) /* ; */])], [ax_pthread_ok=yes], []) CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" AC_MSG_RESULT([$ax_pthread_ok]) AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$ax_pthread_ok" = "xyes"; then ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. AC_CACHE_CHECK([for joinable pthread attribute], [ax_cv_PTHREAD_JOINABLE_ATTR], [ax_cv_PTHREAD_JOINABLE_ATTR=unknown for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], [int attr = $ax_pthread_attr; return attr /* ; */])], [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], []) done ]) AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ test "x$ax_pthread_joinable_attr_defined" != "xyes"], [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$ax_cv_PTHREAD_JOINABLE_ATTR], [Define to necessary symbol if this constant uses a non-standard name on your system.]) ax_pthread_joinable_attr_defined=yes ]) AC_CACHE_CHECK([whether more special flags are required for pthreads], [ax_cv_PTHREAD_SPECIAL_FLAGS], [ax_cv_PTHREAD_SPECIAL_FLAGS=no case $host_os in solaris*) ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" ;; esac ]) AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ test "x$ax_pthread_special_flags_added" != "xyes"], [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" ax_pthread_special_flags_added=yes]) AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], [ax_cv_PTHREAD_PRIO_INHERIT], [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])], [ax_cv_PTHREAD_PRIO_INHERIT=yes], [ax_cv_PTHREAD_PRIO_INHERIT=no]) ]) AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ test "x$ax_pthread_prio_inherit_defined" != "xyes"], [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) ax_pthread_prio_inherit_defined=yes ]) CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" # More AIX lossage: compile with *_r variant if test "x$GCC" != "xyes"; then case $host_os in aix*) AS_CASE(["x/$CC"], [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], [#handle absolute path differently from PATH based program lookup AS_CASE(["x$CC"], [x/*], [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) ;; esac fi fi test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" AC_SUBST([PTHREAD_LIBS]) AC_SUBST([PTHREAD_CFLAGS]) AC_SUBST([PTHREAD_CC]) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test "x$ax_pthread_ok" = "xyes"; then ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) : else ax_pthread_ok=no $2 fi AC_LANG_POP ])dnl AX_PTHREAD libtcod-1.6.4+dfsg/build/autotools/m4/libtool.m4000066400000000000000000010601111321276576200214520ustar00rootroot00000000000000# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) # serial 57 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_CC_BASENAME(CC) # ------------------- # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. m4_defun([_LT_CC_BASENAME], [for cc_temp in $1""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from `configure', and `config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # `config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain="$ac_aux_dir/ltmain.sh" ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the `libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to `config.status' so that its # declaration there will have the same value as in `configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags="_LT_TAGS"dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the `libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into `config.status', and then the shell code to quote escape them in # for loops in `config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # `#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test $lt_write_fail = 0 && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ \`$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test $[#] != 0 do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try \`$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try \`$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test "$silent" = yes && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # _LT_COPYING _LT_LIBTOOL_TAGS # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) _LT_PROG_REPLACE_SHELLFNS mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS="$save_LDFLAGS" ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[[012]]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test "$lt_cv_ld_force_load" = "yes"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" m4_if([$1], [CXX], [ if test "$lt_cv_apple_cc_single_mod" != "yes"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script which will find a shell with a builtin # printf (which we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case "$ECHO" in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [ --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified).], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([${with_sysroot}]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and in which our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test x"[$]$2" = xyes; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" ]) if test x"[$]$2" = xyes; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n $lt_cv_sys_max_cmd_len ; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "$cross_compiling" = yes; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen="shl_load"], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) ]) ]) ]) ]) ]) ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links="nottested" if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test "$hard_links" = no; then AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", [Define to the sub-directory in which libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existent directories. if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[[89]] | openbsd2.[[89]].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([], [sys_lib_dlsearch_path_spec], [2], [Run-time system search path for libraries]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program which can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$1; then lt_cv_path_MAGIC_CMD="$ac_dir/$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac]) MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program which can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi]) if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM="-lm") ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test "$GCC" = yes; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global defined # symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi _LT_TAGVAR(link_all_deplibs, $1)=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS="$save_LDFLAGS"]) if test "$lt_cv_irix_exported_symbol" = yes; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' else case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ;; esac fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting ${shlibpath_var} if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC="$CC" AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report which library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC="$lt_save_CC" ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ func_to_tool_file "$lt_outputfile"~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd2*) # C++ shared libraries are fairly broken _LT_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(GCC, $1)="$GXX" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case ${prev}${p} in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test "$pre_test_object_deps_done" = no; then case ${prev} in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)="${prev}${p}" else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)="$p" else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)="$p" else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test "X$F77" = "Xno"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_F77" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$G77" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" CFLAGS="$lt_save_CFLAGS" fi # test "$_lt_disable_F77" != yes AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test "X$FC" = "Xno"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_FC" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test "$_lt_disable_FC" != yes AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test $lt_ac_count -gt 10 && break lt_ac_count=`expr $lt_ac_count + 1` if test $lt_ac_count -gt $lt_ac_max; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [AC_MSG_CHECKING([whether the shell understands some XSI constructs]) # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes AC_MSG_RESULT([$xsi_shell]) _LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) AC_MSG_CHECKING([whether the shell understands "+="]) lt_shell_append=no ( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes AC_MSG_RESULT([$lt_shell_append]) _LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) # ------------------------------------------------------ # In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and # '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. m4_defun([_LT_PROG_FUNCTION_REPLACE], [dnl { sed -e '/^$1 ()$/,/^} # $1 /c\ $1 ()\ {\ m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) } # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: ]) # _LT_PROG_REPLACE_SHELLFNS # ------------------------- # Replace existing portable implementations of several shell functions with # equivalent extended shell implementations where those features are available.. m4_defun([_LT_PROG_REPLACE_SHELLFNS], [if test x"$xsi_shell" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"}]) _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl func_split_long_opt_name=${1%%=*} func_split_long_opt_arg=${1#*=}]) _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) fi if test x"$lt_shell_append" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl func_quote_for_eval "${2}" dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) fi ]) # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine which file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS libtcod-1.6.4+dfsg/build/autotools/m4/ltoptions.m4000066400000000000000000000300731321276576200220440ustar00rootroot00000000000000# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, # Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 7 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option `$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl `shared' nor `disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the `shared' and # `disable-shared' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the `static' and # `disable-static' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the `fast-install' # and `disable-fast-install' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the `pic-only' and `no-pic' # LT_INIT options. # MODE is either `yes' or `no'. If omitted, it defaults to `both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac], [pic_mode=default]) test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) libtcod-1.6.4+dfsg/build/autotools/m4/ltsugar.m4000066400000000000000000000104241321276576200214700ustar00rootroot00000000000000# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59 which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) libtcod-1.6.4+dfsg/build/autotools/m4/ltversion.m4000066400000000000000000000012621321276576200220340ustar00rootroot00000000000000# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 3337 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.2]) m4_define([LT_PACKAGE_REVISION], [1.3337]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.2' macro_revision='1.3337' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) libtcod-1.6.4+dfsg/build/autotools/m4/lt~obsolete.m4000066400000000000000000000137561321276576200223740ustar00rootroot00000000000000# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) libtcod-1.6.4+dfsg/build/msvs/000077500000000000000000000000001321276576200161635ustar00rootroot00000000000000libtcod-1.6.4+dfsg/build/msvs/common.props000066400000000000000000000011451321276576200205410ustar00rootroot00000000000000 $(SolutionDir)..\..\include;%(AdditionalIncludeDirectories) _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) libtcod-1.6.4+dfsg/build/msvs/core.props000066400000000000000000000012111321276576200201730ustar00rootroot00000000000000 libtcod LIBTCOD_EXPORTS;%(PreprocessorDefinitions) $(SolutionDir)..\..\include;$(SolutionDir)..\..\src\zlib;%(AdditionalIncludeDirectories) libtcod-1.6.4+dfsg/build/msvs/doctcod.vcxproj000066400000000000000000000206631321276576200212260ustar00rootroot00000000000000 Debug Win32 Release Win32 Debug x64 Release x64 {37AB5715-48D7-4BF2-BC39-21A141CCB85C} Win32Proj doctcod 8.1 Application true v140 NotSet Application false v140 true NotSet Application true v140 NotSet Application false v140 true NotSet true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ false $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ false $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ NotUsing Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true Console true NotUsing Level3 Disabled _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true Console true libtcod.lib;%(AdditionalDependencies) Level3 NotUsing MaxSpeed true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true Console true true true Level3 NotUsing MaxSpeed true true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true Console true true true libtcod.lib;%(AdditionalDependencies) libtcod-1.6.4+dfsg/build/msvs/doctcod.vcxproj.filters000066400000000000000000000020061321276576200226640ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files libtcod-1.6.4+dfsg/build/msvs/frost.vcxproj000066400000000000000000000223601321276576200207400ustar00rootroot00000000000000 Debug Win32 Debug x64 Release Win32 Release x64 {ACA2F4A0-911A-4A1A-BB7B-1D768C5C2E01} Win32Proj frost Application true v140 NotSet Application true v140 NotSet Application false v140 true NotSet Application false v140 true NotSet PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ false $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ false $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ Level3 Disabled WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) true Level3 Disabled WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) true Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) true true true Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) true true true libtcod-1.6.4+dfsg/build/msvs/frost.vcxproj.filters000066400000000000000000000016741321276576200224140ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files libtcod-1.6.4+dfsg/build/msvs/gui.props000066400000000000000000000013531321276576200200360ustar00rootroot00000000000000 $(SolutionDir)..\..\include\gui;%(AdditionalIncludeDirectories) libtcod.lib;%(AdditionalDependencies) $(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories) libtcod-1.6.4+dfsg/build/msvs/libtcod-gui.vcxproj000066400000000000000000000227101321276576200220040ustar00rootroot00000000000000 Debug Win32 Debug x64 Release Win32 Release x64 {1A754D9A-D06F-4DE4-BB32-896B93C7C360} Win32Proj libtcodgui DynamicLibrary true v140 DynamicLibrary true v140 DynamicLibrary false v140 true DynamicLibrary false v140 true true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ false $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ false $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ Level3 Disabled WIN32;TCOD_SDL2;_DEBUG;_WINDOWS;_USRDLL;LIBTCOD_GUI_EXPORTS;%(PreprocessorDefinitions) Windows true Level3 Disabled WIN32;TCOD_SDL2;_DEBUG;_WINDOWS;_USRDLL;LIBTCOD_GUI_EXPORTS;%(PreprocessorDefinitions) Console true 5.02 Level3 MaxSpeed true true WIN32;TCOD_SDL2;NDEBUG;_WINDOWS;_USRDLL;LIBTCOD_GUI_EXPORTS;%(PreprocessorDefinitions) Windows true true true Level3 MaxSpeed true true WIN32;TCOD_SDL2;NDEBUG;_WINDOWS;_USRDLL;LIBTCOD_GUI_EXPORTS;%(PreprocessorDefinitions) Console true true true 5.02 libtcod-1.6.4+dfsg/build/msvs/libtcod-gui.vcxproj.filters000066400000000000000000000100001321276576200234400ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files libtcod-1.6.4+dfsg/build/msvs/libtcod.sln000066400000000000000000000322721321276576200203270ustar00rootroot00000000000000 Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26430.14 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libtcod_sdl", "libtcod.vcxproj", "{D6197244-2BEB-4AED-988E-CC1F0B647055}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libtcod-gui", "libtcod-gui.vcxproj", "{1A754D9A-D06F-4DE4-BB32-896B93C7C360}" ProjectSection(ProjectDependencies) = postProject {D6197244-2BEB-4AED-988E-CC1F0B647055} = {D6197244-2BEB-4AED-988E-CC1F0B647055} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "samples_c", "samples_c.vcxproj", "{BC61B446-B53A-4A57-9722-86926F272061}" ProjectSection(ProjectDependencies) = postProject {D6197244-2BEB-4AED-988E-CC1F0B647055} = {D6197244-2BEB-4AED-988E-CC1F0B647055} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "samples_cpp", "samples_cpp.vcxproj", "{21EA5A6A-100A-4B9E-B395-1B6602148AE5}" ProjectSection(ProjectDependencies) = postProject {D6197244-2BEB-4AED-988E-CC1F0B647055} = {D6197244-2BEB-4AED-988E-CC1F0B647055} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "navier", "navier.vcxproj", "{78CFA089-5E94-4BAB-9BF6-11ED34B76276}" ProjectSection(ProjectDependencies) = postProject {D6197244-2BEB-4AED-988E-CC1F0B647055} = {D6197244-2BEB-4AED-988E-CC1F0B647055} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "frost", "frost.vcxproj", "{ACA2F4A0-911A-4A1A-BB7B-1D768C5C2E01}" ProjectSection(ProjectDependencies) = postProject {D6197244-2BEB-4AED-988E-CC1F0B647055} = {D6197244-2BEB-4AED-988E-CC1F0B647055} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rad", "rad.vcxproj", "{D0B9F968-2E1F-478B-8C68-7B4B95B99587}" ProjectSection(ProjectDependencies) = postProject {D6197244-2BEB-4AED-988E-CC1F0B647055} = {D6197244-2BEB-4AED-988E-CC1F0B647055} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ripples", "ripples.vcxproj", "{BF3F99B4-14E9-46B3-B378-6204B7D22104}" ProjectSection(ProjectDependencies) = postProject {D6197244-2BEB-4AED-988E-CC1F0B647055} = {D6197244-2BEB-4AED-988E-CC1F0B647055} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "weather", "weather.vcxproj", "{2158F1B7-DDE9-4F0E-9D38-70EFFC153AD8}" ProjectSection(ProjectDependencies) = postProject {D6197244-2BEB-4AED-988E-CC1F0B647055} = {D6197244-2BEB-4AED-988E-CC1F0B647055} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doctcod", "doctcod.vcxproj", "{37AB5715-48D7-4BF2-BC39-21A141CCB85C}" ProjectSection(ProjectDependencies) = postProject {D6197244-2BEB-4AED-988E-CC1F0B647055} = {D6197244-2BEB-4AED-988E-CC1F0B647055} EndProjectSection EndProject Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "python", "..\..\python\python.pyproj", "{9F5A5967-268C-4D0D-A182-4112A94ABE4B}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libtcod_sdl_opengl", "libtcod_sdl_opengl.vcxproj", "{A56B29B9-036F-401A-B371-7ABB29A91640}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libtcod_bare", "libtcod_bare.vcxproj", "{1088AC48-758B-45FD-8DBF-5A495E3374DA}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Release|Any CPU = Release|Any CPU Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {D6197244-2BEB-4AED-988E-CC1F0B647055}.Debug|Any CPU.ActiveCfg = Debug|Win32 {D6197244-2BEB-4AED-988E-CC1F0B647055}.Debug|Win32.ActiveCfg = Debug|Win32 {D6197244-2BEB-4AED-988E-CC1F0B647055}.Debug|Win32.Build.0 = Debug|Win32 {D6197244-2BEB-4AED-988E-CC1F0B647055}.Debug|x64.ActiveCfg = Debug|x64 {D6197244-2BEB-4AED-988E-CC1F0B647055}.Debug|x64.Build.0 = Debug|x64 {D6197244-2BEB-4AED-988E-CC1F0B647055}.Release|Any CPU.ActiveCfg = Release|Win32 {D6197244-2BEB-4AED-988E-CC1F0B647055}.Release|Win32.ActiveCfg = Release|Win32 {D6197244-2BEB-4AED-988E-CC1F0B647055}.Release|Win32.Build.0 = Release|Win32 {D6197244-2BEB-4AED-988E-CC1F0B647055}.Release|x64.ActiveCfg = Release|x64 {D6197244-2BEB-4AED-988E-CC1F0B647055}.Release|x64.Build.0 = Release|x64 {1A754D9A-D06F-4DE4-BB32-896B93C7C360}.Debug|Any CPU.ActiveCfg = Debug|Win32 {1A754D9A-D06F-4DE4-BB32-896B93C7C360}.Debug|Win32.ActiveCfg = Debug|Win32 {1A754D9A-D06F-4DE4-BB32-896B93C7C360}.Debug|Win32.Build.0 = Debug|Win32 {1A754D9A-D06F-4DE4-BB32-896B93C7C360}.Debug|x64.ActiveCfg = Debug|x64 {1A754D9A-D06F-4DE4-BB32-896B93C7C360}.Debug|x64.Build.0 = Debug|x64 {1A754D9A-D06F-4DE4-BB32-896B93C7C360}.Release|Any CPU.ActiveCfg = Release|Win32 {1A754D9A-D06F-4DE4-BB32-896B93C7C360}.Release|Win32.ActiveCfg = Release|Win32 {1A754D9A-D06F-4DE4-BB32-896B93C7C360}.Release|Win32.Build.0 = Release|Win32 {1A754D9A-D06F-4DE4-BB32-896B93C7C360}.Release|x64.ActiveCfg = Release|x64 {1A754D9A-D06F-4DE4-BB32-896B93C7C360}.Release|x64.Build.0 = Release|x64 {BC61B446-B53A-4A57-9722-86926F272061}.Debug|Any CPU.ActiveCfg = Debug|Win32 {BC61B446-B53A-4A57-9722-86926F272061}.Debug|Win32.ActiveCfg = Debug|Win32 {BC61B446-B53A-4A57-9722-86926F272061}.Debug|Win32.Build.0 = Debug|Win32 {BC61B446-B53A-4A57-9722-86926F272061}.Debug|x64.ActiveCfg = Debug|x64 {BC61B446-B53A-4A57-9722-86926F272061}.Debug|x64.Build.0 = Debug|x64 {BC61B446-B53A-4A57-9722-86926F272061}.Release|Any CPU.ActiveCfg = Release|Win32 {BC61B446-B53A-4A57-9722-86926F272061}.Release|Win32.ActiveCfg = Release|Win32 {BC61B446-B53A-4A57-9722-86926F272061}.Release|Win32.Build.0 = Release|Win32 {BC61B446-B53A-4A57-9722-86926F272061}.Release|x64.ActiveCfg = Release|x64 {BC61B446-B53A-4A57-9722-86926F272061}.Release|x64.Build.0 = Release|x64 {21EA5A6A-100A-4B9E-B395-1B6602148AE5}.Debug|Any CPU.ActiveCfg = Debug|Win32 {21EA5A6A-100A-4B9E-B395-1B6602148AE5}.Debug|Win32.ActiveCfg = Debug|Win32 {21EA5A6A-100A-4B9E-B395-1B6602148AE5}.Debug|Win32.Build.0 = Debug|Win32 {21EA5A6A-100A-4B9E-B395-1B6602148AE5}.Debug|x64.ActiveCfg = Debug|x64 {21EA5A6A-100A-4B9E-B395-1B6602148AE5}.Debug|x64.Build.0 = Debug|x64 {21EA5A6A-100A-4B9E-B395-1B6602148AE5}.Release|Any CPU.ActiveCfg = Release|Win32 {21EA5A6A-100A-4B9E-B395-1B6602148AE5}.Release|Win32.ActiveCfg = Release|Win32 {21EA5A6A-100A-4B9E-B395-1B6602148AE5}.Release|Win32.Build.0 = Release|Win32 {21EA5A6A-100A-4B9E-B395-1B6602148AE5}.Release|x64.ActiveCfg = Release|x64 {21EA5A6A-100A-4B9E-B395-1B6602148AE5}.Release|x64.Build.0 = Release|x64 {78CFA089-5E94-4BAB-9BF6-11ED34B76276}.Debug|Any CPU.ActiveCfg = Debug|Win32 {78CFA089-5E94-4BAB-9BF6-11ED34B76276}.Debug|Win32.ActiveCfg = Debug|Win32 {78CFA089-5E94-4BAB-9BF6-11ED34B76276}.Debug|Win32.Build.0 = Debug|Win32 {78CFA089-5E94-4BAB-9BF6-11ED34B76276}.Debug|x64.ActiveCfg = Debug|x64 {78CFA089-5E94-4BAB-9BF6-11ED34B76276}.Debug|x64.Build.0 = Debug|x64 {78CFA089-5E94-4BAB-9BF6-11ED34B76276}.Release|Any CPU.ActiveCfg = Release|Win32 {78CFA089-5E94-4BAB-9BF6-11ED34B76276}.Release|Win32.ActiveCfg = Release|Win32 {78CFA089-5E94-4BAB-9BF6-11ED34B76276}.Release|Win32.Build.0 = Release|Win32 {78CFA089-5E94-4BAB-9BF6-11ED34B76276}.Release|x64.ActiveCfg = Release|x64 {78CFA089-5E94-4BAB-9BF6-11ED34B76276}.Release|x64.Build.0 = Release|x64 {ACA2F4A0-911A-4A1A-BB7B-1D768C5C2E01}.Debug|Any CPU.ActiveCfg = Debug|Win32 {ACA2F4A0-911A-4A1A-BB7B-1D768C5C2E01}.Debug|Win32.ActiveCfg = Debug|Win32 {ACA2F4A0-911A-4A1A-BB7B-1D768C5C2E01}.Debug|Win32.Build.0 = Debug|Win32 {ACA2F4A0-911A-4A1A-BB7B-1D768C5C2E01}.Debug|x64.ActiveCfg = Debug|x64 {ACA2F4A0-911A-4A1A-BB7B-1D768C5C2E01}.Debug|x64.Build.0 = Debug|x64 {ACA2F4A0-911A-4A1A-BB7B-1D768C5C2E01}.Release|Any CPU.ActiveCfg = Release|Win32 {ACA2F4A0-911A-4A1A-BB7B-1D768C5C2E01}.Release|Win32.ActiveCfg = Release|Win32 {ACA2F4A0-911A-4A1A-BB7B-1D768C5C2E01}.Release|Win32.Build.0 = Release|Win32 {ACA2F4A0-911A-4A1A-BB7B-1D768C5C2E01}.Release|x64.ActiveCfg = Release|x64 {ACA2F4A0-911A-4A1A-BB7B-1D768C5C2E01}.Release|x64.Build.0 = Release|x64 {D0B9F968-2E1F-478B-8C68-7B4B95B99587}.Debug|Any CPU.ActiveCfg = Debug|Win32 {D0B9F968-2E1F-478B-8C68-7B4B95B99587}.Debug|Win32.ActiveCfg = Debug|Win32 {D0B9F968-2E1F-478B-8C68-7B4B95B99587}.Debug|Win32.Build.0 = Debug|Win32 {D0B9F968-2E1F-478B-8C68-7B4B95B99587}.Debug|x64.ActiveCfg = Debug|x64 {D0B9F968-2E1F-478B-8C68-7B4B95B99587}.Debug|x64.Build.0 = Debug|x64 {D0B9F968-2E1F-478B-8C68-7B4B95B99587}.Release|Any CPU.ActiveCfg = Release|Win32 {D0B9F968-2E1F-478B-8C68-7B4B95B99587}.Release|Win32.ActiveCfg = Release|Win32 {D0B9F968-2E1F-478B-8C68-7B4B95B99587}.Release|Win32.Build.0 = Release|Win32 {D0B9F968-2E1F-478B-8C68-7B4B95B99587}.Release|x64.ActiveCfg = Release|x64 {D0B9F968-2E1F-478B-8C68-7B4B95B99587}.Release|x64.Build.0 = Release|x64 {BF3F99B4-14E9-46B3-B378-6204B7D22104}.Debug|Any CPU.ActiveCfg = Debug|Win32 {BF3F99B4-14E9-46B3-B378-6204B7D22104}.Debug|Win32.ActiveCfg = Debug|Win32 {BF3F99B4-14E9-46B3-B378-6204B7D22104}.Debug|Win32.Build.0 = Debug|Win32 {BF3F99B4-14E9-46B3-B378-6204B7D22104}.Debug|x64.ActiveCfg = Debug|x64 {BF3F99B4-14E9-46B3-B378-6204B7D22104}.Debug|x64.Build.0 = Debug|x64 {BF3F99B4-14E9-46B3-B378-6204B7D22104}.Release|Any CPU.ActiveCfg = Release|Win32 {BF3F99B4-14E9-46B3-B378-6204B7D22104}.Release|Win32.ActiveCfg = Release|Win32 {BF3F99B4-14E9-46B3-B378-6204B7D22104}.Release|Win32.Build.0 = Release|Win32 {BF3F99B4-14E9-46B3-B378-6204B7D22104}.Release|x64.ActiveCfg = Release|x64 {BF3F99B4-14E9-46B3-B378-6204B7D22104}.Release|x64.Build.0 = Release|x64 {2158F1B7-DDE9-4F0E-9D38-70EFFC153AD8}.Debug|Any CPU.ActiveCfg = Debug|Win32 {2158F1B7-DDE9-4F0E-9D38-70EFFC153AD8}.Debug|Win32.ActiveCfg = Debug|Win32 {2158F1B7-DDE9-4F0E-9D38-70EFFC153AD8}.Debug|Win32.Build.0 = Debug|Win32 {2158F1B7-DDE9-4F0E-9D38-70EFFC153AD8}.Debug|x64.ActiveCfg = Debug|x64 {2158F1B7-DDE9-4F0E-9D38-70EFFC153AD8}.Debug|x64.Build.0 = Debug|x64 {2158F1B7-DDE9-4F0E-9D38-70EFFC153AD8}.Release|Any CPU.ActiveCfg = Release|Win32 {2158F1B7-DDE9-4F0E-9D38-70EFFC153AD8}.Release|Win32.ActiveCfg = Release|Win32 {2158F1B7-DDE9-4F0E-9D38-70EFFC153AD8}.Release|Win32.Build.0 = Release|Win32 {2158F1B7-DDE9-4F0E-9D38-70EFFC153AD8}.Release|x64.ActiveCfg = Release|x64 {2158F1B7-DDE9-4F0E-9D38-70EFFC153AD8}.Release|x64.Build.0 = Release|x64 {37AB5715-48D7-4BF2-BC39-21A141CCB85C}.Debug|Any CPU.ActiveCfg = Debug|Win32 {37AB5715-48D7-4BF2-BC39-21A141CCB85C}.Debug|Win32.ActiveCfg = Debug|Win32 {37AB5715-48D7-4BF2-BC39-21A141CCB85C}.Debug|Win32.Build.0 = Debug|Win32 {37AB5715-48D7-4BF2-BC39-21A141CCB85C}.Debug|x64.ActiveCfg = Debug|x64 {37AB5715-48D7-4BF2-BC39-21A141CCB85C}.Debug|x64.Build.0 = Debug|x64 {37AB5715-48D7-4BF2-BC39-21A141CCB85C}.Release|Any CPU.ActiveCfg = Release|Win32 {37AB5715-48D7-4BF2-BC39-21A141CCB85C}.Release|Win32.ActiveCfg = Release|Win32 {37AB5715-48D7-4BF2-BC39-21A141CCB85C}.Release|Win32.Build.0 = Release|Win32 {37AB5715-48D7-4BF2-BC39-21A141CCB85C}.Release|x64.ActiveCfg = Release|x64 {37AB5715-48D7-4BF2-BC39-21A141CCB85C}.Release|x64.Build.0 = Release|x64 {9F5A5967-268C-4D0D-A182-4112A94ABE4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9F5A5967-268C-4D0D-A182-4112A94ABE4B}.Debug|Win32.ActiveCfg = Debug|Any CPU {9F5A5967-268C-4D0D-A182-4112A94ABE4B}.Debug|x64.ActiveCfg = Debug|Any CPU {9F5A5967-268C-4D0D-A182-4112A94ABE4B}.Release|Any CPU.ActiveCfg = Release|Any CPU {9F5A5967-268C-4D0D-A182-4112A94ABE4B}.Release|Win32.ActiveCfg = Release|Any CPU {9F5A5967-268C-4D0D-A182-4112A94ABE4B}.Release|x64.ActiveCfg = Release|Any CPU {A56B29B9-036F-401A-B371-7ABB29A91640}.Debug|Any CPU.ActiveCfg = Debug|Win32 {A56B29B9-036F-401A-B371-7ABB29A91640}.Debug|Win32.ActiveCfg = Debug|Win32 {A56B29B9-036F-401A-B371-7ABB29A91640}.Debug|Win32.Build.0 = Debug|Win32 {A56B29B9-036F-401A-B371-7ABB29A91640}.Debug|x64.ActiveCfg = Debug|x64 {A56B29B9-036F-401A-B371-7ABB29A91640}.Debug|x64.Build.0 = Debug|x64 {A56B29B9-036F-401A-B371-7ABB29A91640}.Release|Any CPU.ActiveCfg = Release|Win32 {A56B29B9-036F-401A-B371-7ABB29A91640}.Release|Win32.ActiveCfg = Release|Win32 {A56B29B9-036F-401A-B371-7ABB29A91640}.Release|Win32.Build.0 = Release|Win32 {A56B29B9-036F-401A-B371-7ABB29A91640}.Release|x64.ActiveCfg = Release|x64 {A56B29B9-036F-401A-B371-7ABB29A91640}.Release|x64.Build.0 = Release|x64 {1088AC48-758B-45FD-8DBF-5A495E3374DA}.Debug|Any CPU.ActiveCfg = Debug|Win32 {1088AC48-758B-45FD-8DBF-5A495E3374DA}.Debug|Win32.ActiveCfg = Debug|Win32 {1088AC48-758B-45FD-8DBF-5A495E3374DA}.Debug|Win32.Build.0 = Debug|Win32 {1088AC48-758B-45FD-8DBF-5A495E3374DA}.Debug|x64.ActiveCfg = Debug|x64 {1088AC48-758B-45FD-8DBF-5A495E3374DA}.Debug|x64.Build.0 = Debug|x64 {1088AC48-758B-45FD-8DBF-5A495E3374DA}.Release|Any CPU.ActiveCfg = Release|Win32 {1088AC48-758B-45FD-8DBF-5A495E3374DA}.Release|Win32.ActiveCfg = Release|Win32 {1088AC48-758B-45FD-8DBF-5A495E3374DA}.Release|Win32.Build.0 = Release|Win32 {1088AC48-758B-45FD-8DBF-5A495E3374DA}.Release|x64.ActiveCfg = Release|x64 {1088AC48-758B-45FD-8DBF-5A495E3374DA}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal libtcod-1.6.4+dfsg/build/msvs/libtcod.vcxproj000066400000000000000000000356661321276576200212400ustar00rootroot00000000000000 Debug Win32 Debug x64 Release Win32 Release x64 {D6197244-2BEB-4AED-988E-CC1F0B647055} Win32Proj libtcod_sdl 8.1 DynamicLibrary true v140_xp DynamicLibrary true v140_xp DynamicLibrary false v140_xp DynamicLibrary false v140_xp true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ WIN32;NO_OPENGL;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) MultiThreadedDebugDLL Level3 ProgramDatabase Disabled $(SolutionDir)..\dependencies\include;$(SolutionDir)..\..\src\zlib;%(AdditionalIncludeDirectories) MachineX86 true Console 5.01 SDL2.lib;%(AdditionalDependencies) WIN32;NO_OPENGL;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) MultiThreadedDebugDLL Level3 ProgramDatabase Disabled true Console 5.02 SDL2.lib;%(AdditionalDependencies) WIN32;NO_OPENGL;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) MultiThreadedDLL Level3 ProgramDatabase $(SolutionDir)..\dependencies\include;$(SolutionDir)..\..\src\zlib;%(AdditionalIncludeDirectories) MachineX86 true Console true true 5.01 SDL2.lib;%(AdditionalDependencies) WIN32;NO_OPENGL;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) MultiThreadedDLL Level3 ProgramDatabase true Console true true 5.02 SDL2.lib;%(AdditionalDependencies) libtcod-1.6.4+dfsg/build/msvs/libtcod.vcxproj.filters000066400000000000000000000347721321276576200227040ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav {87278468-d8a8-4ddc-93c8-e49d383e2900} {f73c2e99-ca6d-46a1-8cf4-8ec93ba6ce01} {165e875a-1b94-4a1a-9d66-1901dfe3f661} {e6410117-0a59-4966-83ae-729990596a7a} {90ee66c0-9b9b-4dc9-89be-296a1b942da9} {63e6f9f2-e655-4ffa-8b82-c81e649624dc} {bac2f5e8-48b6-4377-93de-6b317a6bd50d} Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\png Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files\zlib Header Files\zlib Header Files\zlib Header Files\zlib Header Files\zlib Header Files\zlib Header Files\zlib Header Files\zlib Header Files\zlib Header Files\zlib Header Files\png Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\external libtcod-1.6.4+dfsg/build/msvs/libtcod_bare.vcxproj000066400000000000000000000350371321276576200222210ustar00rootroot00000000000000 Debug Win32 Debug x64 Release Win32 Release x64 {1088AC48-758B-45FD-8DBF-5A495E3374DA} Win32Proj 8.1 DynamicLibrary true v140_xp DynamicLibrary true v140_xp DynamicLibrary false v140_xp DynamicLibrary false v140_xp true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) MultiThreadedDebugDLL Level3 ProgramDatabase Disabled $(SolutionDir)..\dependencies\include;$(SolutionDir)..\..\src\zlib;%(AdditionalIncludeDirectories) MachineX86 true Console 5.01 WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) MultiThreadedDebugDLL Level3 ProgramDatabase Disabled true Console 5.02 WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) MultiThreadedDLL Level3 ProgramDatabase $(SolutionDir)..\dependencies\include;$(SolutionDir)..\..\src\zlib;%(AdditionalIncludeDirectories) MachineX86 true Console true true 5.01 WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) MultiThreadedDLL Level3 ProgramDatabase true Console true true 5.02 libtcod-1.6.4+dfsg/build/msvs/libtcod_bare.vcxproj.filters000066400000000000000000000355131321276576200236670ustar00rootroot00000000000000 {4FC737F2-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995381-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {67DA6AB7-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav {87278469-d8a8-4ddc-93c8-e49d383e2900} {f73c2e91-ca6d-46a1-8cf4-8ec93ba6ce01} {165e8752-1b94-4a1a-9d66-1901dfe3f661} {e6410113-0a59-4966-83ae-729990596a7a} {90ee66c4-9b9b-4dc9-89be-296a1b942da9} {63e6f9f4-e655-4ffa-8b82-c81e649624dc} {bac2f5e4-48b6-4377-93de-6b317a6bd50d} Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\png Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files\zlib Header Files\zlib Header Files\zlib Header Files\zlib Header Files\zlib Header Files\zlib Header Files\zlib Header Files\zlib Header Files\zlib Header Files\zlib Header Files\png Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\external Header Files Header Files Header Files libtcod-1.6.4+dfsg/build/msvs/libtcod_sdl_opengl.vcxproj000066400000000000000000000356271321276576200234430ustar00rootroot00000000000000 Debug Win32 Debug x64 Release Win32 Release x64 {A56B29B9-036F-401A-B371-7ABB29A91640} Win32Proj 8.1 DynamicLibrary true v140_xp DynamicLibrary true v140_xp DynamicLibrary false v140_xp DynamicLibrary false v140_xp true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) MultiThreadedDebugDLL Level3 ProgramDatabase Disabled $(SolutionDir)..\dependencies\include;$(SolutionDir)..\..\src\zlib;%(AdditionalIncludeDirectories) MachineX86 true Console 5.01 SDL2.lib;opengl32.lib;%(AdditionalDependencies) WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) MultiThreadedDebugDLL Level3 ProgramDatabase Disabled true Console 5.02 SDL2.lib;opengl32.lib;%(AdditionalDependencies) WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) MultiThreadedDLL Level3 ProgramDatabase $(SolutionDir)..\dependencies\include;$(SolutionDir)..\..\src\zlib;%(AdditionalIncludeDirectories) MachineX86 true Console true true 5.01 SDL2.lib;opengl32.lib;%(AdditionalDependencies) WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) MultiThreadedDLL Level3 ProgramDatabase true Console true true 5.02 SDL2.lib;opengl32.lib;%(AdditionalDependencies) libtcod-1.6.4+dfsg/build/msvs/libtcod_sdl_opengl.vcxproj.filters000066400000000000000000000347721321276576200251120ustar00rootroot00000000000000 {4FC737F2-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995381-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {67DA6AB7-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav {87278469-d8a8-4ddc-93c8-e49d383e2900} {f73c2e91-ca6d-46a1-8cf4-8ec93ba6ce01} {165e8752-1b94-4a1a-9d66-1901dfe3f661} {e6410113-0a59-4966-83ae-729990596a7a} {90ee66c4-9b9b-4dc9-89be-296a1b942da9} {63e6f9f4-e655-4ffa-8b82-c81e649624dc} {bac2f5e4-48b6-4377-93de-6b317a6bd50d} Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\zlib Source Files\png Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files\cpp Source Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files\zlib Header Files\zlib Header Files\zlib Header Files\zlib Header Files\zlib Header Files\zlib Header Files\zlib Header Files\zlib Header Files\zlib Header Files\zlib Header Files\png Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\cpp Header Files\external libtcod-1.6.4+dfsg/build/msvs/navier.vcxproj000066400000000000000000000224741321276576200210750ustar00rootroot00000000000000 Debug Win32 Debug x64 Release Win32 Release x64 {78CFA089-5E94-4BAB-9BF6-11ED34B76276} Win32Proj navier Application true v140 Application true v140 Application false v140 true Application false v140 true PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ false $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ false $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ Level3 Disabled WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true Level3 Disabled WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true true true Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true true true libtcod-1.6.4+dfsg/build/msvs/navier.vcxproj.filters000066400000000000000000000021061321276576200225320ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Header Files Source Files libtcod-1.6.4+dfsg/build/msvs/rad.vcxproj000066400000000000000000000234321321276576200203520ustar00rootroot00000000000000 Debug Win32 Debug x64 Release Win32 Release x64 {D0B9F968-2E1F-478B-8C68-7B4B95B99587} Win32Proj rad Application true v140 NotSet Application true v140 NotSet Application false v140 true NotSet Application false v140 true NotSet PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ false $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ false $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ Level3 Disabled WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true Level3 Disabled WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true true true Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true true true libtcod-1.6.4+dfsg/build/msvs/rad.vcxproj.filters000066400000000000000000000032061321276576200220160ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files Source Files Source Files Source Files Source Files Header Files Header Files libtcod-1.6.4+dfsg/build/msvs/ripples.vcxproj000066400000000000000000000231451321276576200212630ustar00rootroot00000000000000 Debug Win32 Debug x64 Release Win32 Release x64 {BF3F99B4-14E9-46B3-B378-6204B7D22104} Win32Proj ripples Application true v140 NotSet Application true v140 NotSet Application false v140 true NotSet Application false v140 true NotSet PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ false $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ false $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ Level3 Disabled WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true Level3 Disabled WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true true true Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true true true libtcod-1.6.4+dfsg/build/msvs/ripples.vcxproj.filters000066400000000000000000000024641321276576200227330ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Header Files Header Files Source Files Source Files libtcod-1.6.4+dfsg/build/msvs/samples.props000066400000000000000000000013331321276576200207140ustar00rootroot00000000000000 $(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories) libtcod.lib;%(AdditionalDependencies) Console 5.01 libtcod-1.6.4+dfsg/build/msvs/samples64.props000066400000000000000000000006051321276576200210670ustar00rootroot00000000000000 5.02 libtcod-1.6.4+dfsg/build/msvs/samples_c.vcxproj000066400000000000000000000226101321276576200215470ustar00rootroot00000000000000 Debug Win32 Debug x64 Release Win32 Release x64 {BC61B446-B53A-4A57-9722-86926F272061} Win32Proj samples_c Application true v140 Unicode Application true v140 Unicode Application false v140 true Unicode Application false v140 true Unicode PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ false $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ false $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ Level3 Disabled WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true Level3 Disabled WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true true true Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true true true libtcod-1.6.4+dfsg/build/msvs/samples_c.vcxproj.filters000066400000000000000000000016701321276576200232210ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files libtcod-1.6.4+dfsg/build/msvs/samples_cpp.vcxproj000066400000000000000000000234021321276576200221070ustar00rootroot00000000000000 Debug Win32 Debug x64 Release Win32 Release x64 {21EA5A6A-100A-4B9E-B395-1B6602148AE5} Win32Proj samples_cpp Application true v140 Unicode Application true v140 Unicode Application false v140 true Unicode Application false v140 true Unicode $(SolutionDir)..\..\ PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ $(SolutionDir)..\..\ PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ $(SolutionDir)..\..\ PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger false $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ $(SolutionDir)..\..\ PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger false $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ Level3 Disabled WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true libtcod.lib;%(AdditionalDependencies) Level3 Disabled WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true libtcod.lib;%(AdditionalDependencies) Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true true true libtcod.lib;%(AdditionalDependencies) Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true true true libtcod.lib;%(AdditionalDependencies) libtcod-1.6.4+dfsg/build/msvs/samples_cpp.vcxproj.filters000066400000000000000000000016741321276576200235650ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files libtcod-1.6.4+dfsg/build/msvs/sdl12.props000066400000000000000000000013571321276576200202030ustar00rootroot00000000000000 TCOD_SDL2;%(PreprocessorDefinitions) $(SolutionDir)..\dependencies\include;%(AdditionalIncludeDirectories) $(SolutionDir)..\dependencies\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories) libtcod-1.6.4+dfsg/build/msvs/weather.vcxproj000066400000000000000000000231451321276576200212440ustar00rootroot00000000000000 Debug Win32 Debug x64 Release Win32 Release x64 {2158F1B7-DDE9-4F0E-9D38-70EFFC153AD8} Win32Proj weather Application true v140 NotSet Application true v140 NotSet Application false v140 true NotSet Application false v140 true NotSet PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ true $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ false $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ PATH=%PATH%;$(SolutionDir)libtcod_sdl_opengl\$(Platform)\$(Configuration);$(SolutionDir)..\dependencies\$(Platform)\$(Configuration) $(LocalDebuggerEnvironment) WindowsLocalDebugger $(SolutionDir)..\..\ false $(SolutionDir)$(ProjectName)\$(Platform)\$(Configuration)\ $(ProjectName)\$(Platform)\$(Configuration)\ Level3 Disabled WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true Level3 Disabled WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true true true Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) Console true true true libtcod-1.6.4+dfsg/build/msvs/weather.vcxproj.filters000066400000000000000000000024641321276576200227140ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Header Files Header Files Source Files Source Files libtcod-1.6.4+dfsg/build/scons/000077500000000000000000000000001321276576200163205ustar00rootroot00000000000000libtcod-1.6.4+dfsg/build/scons/README.md000066400000000000000000000030421321276576200175760ustar00rootroot00000000000000If you need to, download Scons from http://scons.org/pages/download.html This builder automatically downloads SDL2 on Windows and Mac as needed. On Linux you must install SDL2 'the Unix way' or by installing the libsdl2-dev package before running this script. On Windows you will need an installation of Microsoft Visual Studio or MinGW. To test this SCons script you can use the `build` alias, which will build libtcod and all samples without touching any files outside of this subdirectory: ``` scons build ``` SCons can compile faster using multiple cores, use the`-j ` flag. To build and install libtcod and all sample programs into the root libtcod folder, use the `develop` alias. The default mode is `MODE=DEBUG`, so you'll also need to change `MODE` if you want a release build: ``` scons develop MODE=RELEASE ``` If you only need to work with the libtcod shared library you can use `develop_libtcod` instead. The compiled binaries will be 32-bit by default. You can compile 64-bit binaries with the `ARCH=x86_64` variable: ``` scons develop MODE=RELEASE ARCH=x86_64 ``` On Mac this script will always make a universal build, ignoring `ARCH`. Windows has the option of using the MSVC compiler (default) or MinGW compiler. To use MinGW set the `TOOLSET=mingw` variable. A packaged release can be made with the `dist` alias. Additional variables can be changed such as the compiler and linker flags. The easiest way to change these options is by editing `config.py`. To see an additional list of extra variables you should run `scons -h`. libtcod-1.6.4+dfsg/build/scons/SConstruct000066400000000000000000000304371321276576200203610ustar00rootroot00000000000000 import os import sys import platform import re import subprocess import tarfile import time import urllib import zipfile import config def ensure_path(path): """Make sure a directory exists for a new file at path.""" path = os.path.dirname(path) if not os.path.isdir(path): os.makedirs(path) def download_sdl2_win32(env): """Download the MinGW or VC development distribution from libsdl.org""" if env.File('$SDL2_ZIP_PATH').exists(): return print(env.subst('Downloading $SDL2_ZIP_URL')) ensure_path(env.subst('$SDL2_ZIP_PATH')) urllib.urlretrieve(env.subst('$SDL2_ZIP_URL'), env.subst('$SDL2_ZIP_PATH')) def unpack_sdl2_win32(env): """Unpack an SDL2 zip/tar file.""" if env.Dir('$SDL2_PATH').exists(): print(env.subst('SDL2 already exists at $SDL2_PATH')) return download_sdl2_win32(env) print(env.subst('Extracting $SDL2_ZIP_FILE to $DEPENDANCY_DIR')) if(env.subst('$SDL2_ZIP_FILE').endswith('.zip')): zf = zipfile.ZipFile(env.subst('$SDL2_ZIP_PATH'), 'r') else: zf = tarfile.open(env.subst('$SDL2_ZIP_PATH'), 'r|*') zf.extractall(env.subst('$DEPENDANCY_DIR')) zf.close() def download_sdl2_darwin(env): """Download the Mac OS/X distribution from libsdl.org""" if env.File('$SDL2_DMG_PATH').exists(): return print(env.subst('Downloading $SDL2_DMG_URL')) ensure_path(env.subst('$SDL2_DMG_PATH')) urllib.urlretrieve(env.subst('$SDL2_DMG_URL'), env.subst('$SDL2_DMG_PATH')) def unpack_sdl2_darwin(env): """Unpack an SDL2 dmg file.""" if env.Dir('$SDL2_PATH').exists(): print(env.subst('SDL2 already exists at $SDL2_PATH')) return download_sdl2_darwin(env) print(env.subst('Extracting $SDL2_DMG_PATH to $DEPENDANCY_DIR')) subprocess.check_call(['hdiutil', 'mount', env.subst('$SDL2_DMG_PATH')]) subprocess.check_call(['cp', '-r', '/Volumes/SDL2/SDL2.framework', env.subst('$DEPENDANCY_DIR')]) subprocess.check_call(['hdiutil', 'unmount', '/Volumes/SDL2']) def samples_factory(): """Return a list of samples builders.""" samples = [] installers = [] env_samples = env.Clone() env_samples.Append(CPPDEFINES=['TCOD_SDL2']) if env['TOOLSET'] == 'mingw': # These might need to be statically linked somewhere. env_libtcod.Append(LINKFLAGS=['-static-libgcc', '-static-libstdc++']) if sys.platform == 'win32': env_samples.Append(LIBS=['libtcod', 'libtcod-gui']) else: env_samples.Append(LIBS=['tcod', 'tcod-gui']) for name in os.listdir(env.subst('$LIBTCOD_ROOT_DIR/samples')): path = os.path.join(env.subst('$LIBTCOD_ROOT_DIR/samples'), name) path_variant = os.path.join(env.subst('$VARIANT/samples'), name) if os.path.isdir(path): target = name source=Glob(os.path.join(path_variant, '*.c*')) elif name[-2:] == '.c' or name[-4:] == '.cpp': target=name.rsplit('.')[0] source=path_variant else: continue target = os.path.join('$VARIANT', target) samples.append( env_samples.Program( target=target, source=source, ) ) env.Depends(samples, [libtcod, libtcod_gui]) return samples def get_libtcod_version(): """Return the latest version number from the CHANGELOG.""" for filename in os.listdir(LIBTCOD_ROOT_DIR): if 'CHANGELOG' not in filename: continue with open(os.path.join(LIBTCOD_ROOT_DIR, filename), 'r') as changelog: # Grab the first thing we see after a "===" separator. return re.match(r'[^=]+=+(?:\r\n?|\n)([^ :]+)', changelog.read()).groups()[0] LIBTCOD_ROOT_DIR = '../..' vars = Variables() pre_vars = Environment(variables=vars) vars.Add('MODE', 'Set build variant.', 'DEBUG') default_toolset = 'msvc' if sys.platform == 'win32' else 'default' vars.Add(EnumVariable('TOOLSET', 'Force using this compiler. (Windows only)', default_toolset, ('default', 'msvc', 'mingw'))) vars.Add('CCFLAGS', 'Compiler flags', '') vars.Add('LINKFLAGS', 'Linker flags', '') vars.Add(EnumVariable('ARCH', 'Set target architecture. (Windows/Linux only)', 'x86', allowed_values=('x86', 'x86_64'))) # A dummy environment to check the current variables so far. env_vars = Environment(variables=vars) if env_vars['TOOLSET'] == 'default': default_tag = '$VERSION-$ARCH' windows_toolset = 'msvc' else: default_tag = '$VERSION-$ARCH-$TOOLSET' windows_toolset = env_vars['TOOLSET'] if env_vars['MODE'].upper() != 'RELEASE': default_tag += '-$MODE' vars.Add('TAG', 'Variant tag.', default_tag) vars.Add('CPPDEFINES', 'Defined preprocessor values.', ' '.join(config.DEFINES)) vars.Add('VERSION', 'libtcod version.', get_libtcod_version()) vars.Add('DIST_NAME', 'Name of the output zip file.', '$VARIANT-$DATETIME') if sys.platform == 'win32': DEPENDANCY_DIR = './dependencies/$WINDOWS_TOOLSET' else: DEPENDANCY_DIR = './dependencies' vars.Add('DEPENDANCY_DIR', 'Directory to cache SDL2.', DEPENDANCY_DIR) vars.Add('SDL2_VERSION', 'SDL version to fetch. (Windows/Mac only)', '2.0.5') if windows_toolset == 'msvc': sdl2_zip_file = 'SDL2-devel-$SDL2_VERSION-VC.zip' else: sdl2_zip_file = 'SDL2-devel-$SDL2_VERSION-mingw.tar.gz' if sys.platform == 'win32': sdl2_path = '$DEPENDANCY_DIR/SDL2-$SDL2_VERSION' elif sys.platform == 'darwin': sdl2_path = '$DEPENDANCY_DIR/SDL2.framework' else: sdl2_path = '' TOOLSETS = {'default': ['default'], 'msvc': ['msvc', 'mslink'], 'mingw': ['mingw'], } env = Environment( tools=TOOLSETS[env_vars['TOOLSET'].lower()] + ['tar', 'zip'], WINDOWS_TOOLSET=windows_toolset, variables=vars, ENV=os.environ, LIBTCOD_ROOT_DIR=LIBTCOD_ROOT_DIR, INSTALL_DIR='$LIBTCOD_ROOT_DIR', CPPPATH=['$VARIANT/include', '$VARIANT/include/gui', '$VARIANT/src/png', '$VARIANT/src/zlib', ], LIBPATH=['$VARIANT'], VARIANT='libtcod-$TAG', DATE=time.strftime("%Y-%m-%d"), DATETIME=time.strftime("%Y-%m-%d-%H%M%S"), TARGET_ARCH = env_vars['ARCH'], SDL2_PATH=sdl2_path, SDL2_ZIP_FILE=sdl2_zip_file, SDL2_ZIP_PATH='$DEPENDANCY_DIR/$SDL2_ZIP_FILE', SDL2_ZIP_URL='https://www.libsdl.org/release/$SDL2_ZIP_FILE', SDL2_DMG_FILE='SDL2-${SDL2_VERSION}.dmg', SDL2_DMG_PATH='$DEPENDANCY_DIR/$SDL2_DMG_FILE', SDL2_DMG_URL='https://www.libsdl.org/release/$SDL2_DMG_FILE', ) env['CCFLAGS'] = Split(env['CCFLAGS']) env['LINKFLAGS'] = Split(env['LINKFLAGS']) env['CPPDEFINES'] = Split(env['CPPDEFINES']) if sys.platform != 'darwin': # Removing the lib prefix on Mac causes a link failure. env.Replace(LIBPREFIX='', SHLIBPREFIX='') env['SDL_ARCH'] = 'x86' if env['ARCH'] == 'x86' else 'x64' env['SDL_MINGW_ARCH'] = 'i686' if env['SDL_ARCH'] == 'x86' else 'x86_64' using_msvc = env['CC'] == 'cl' CONFIG_NAME = '%s_%s' % (env['MODE'].upper(), 'MSVC' if using_msvc else 'GCC') env.Prepend(**getattr(config, CONFIG_NAME)) sdl_package = [] sdl_install = [] if sys.platform == 'win32': unpack_sdl2_win32(env) if using_msvc: env.Append(CPPDEFINES=['_CRT_SECURE_NO_WARNINGS']) env.Append(LIBS=['User32']) if env['WINDOWS_TOOLSET'] == 'msvc': env.Append(CPPPATH=['$SDL2_PATH/include'], LIBPATH=['$SDL2_PATH/lib/$SDL_ARCH']) sdl_install = env.Install('$INSTALL_DIR', '$SDL2_PATH/lib/$SDL_ARCH/SDL2.dll') sdl_package = env.Install('$VARIANT', '$SDL2_PATH/lib/$SDL_ARCH/SDL2.dll') else: # I couldn't get sdl2-config to run on Windows # `sdl2-config --cflags --libs` is manually unpacked here env.Append( CPPPATH=['$SDL2_PATH/$SDL_MINGW_ARCH-w64-mingw32/include/SDL2'], LIBPATH=['$SDL2_PATH/$SDL_MINGW_ARCH-w64-mingw32/lib'], CCFLAGS=['-mwindows'], LIBS=['mingw32', 'SDL2main', 'SDL2'], #CPPDEFINES=['main=SDL_main'], ) sdl_install = env.Install( '$INSTALL_DIR', '$SDL2_PATH/$SDL_MINGW_ARCH-w64-mingw32/bin/SDL2.dll' ) sdl_package = env.Install( '$VARIANT', '$SDL2_PATH/$SDL_MINGW_ARCH-w64-mingw32/bin/SDL2.dll' ) elif sys.platform == 'darwin': unpack_sdl2_darwin(env) env['ARCH'] = 'x86.x86_64' env.Append(CPPPATH=['$SDL2_PATH/Headers']) sdl_install = env.Install('$INSTALL_DIR', '$SDL2_PATH') sdl_package = env.Install('$VARIANT', '$SDL2_PATH') else: env.ParseConfig("sdl2-config --cflags --libs") env.Append(LIBS=['m']) if sys.platform == 'darwin': OSX_FLAGS = ['-arch', 'i386', '-arch', 'x86_64'] env.Append(CCFLAGS=OSX_FLAGS, LINKFLAGS=OSX_FLAGS) # Added a ton ot rpath's. # Only '@loader_path/' is actually needed. env.Append(LINKFLAGS=['-framework', 'ApplicationServices', '-framework', 'SDL2', '-F$SDL2_PATH/..', '-rpath', '@loader_path/', '-rpath', '@loader_path/../Frameworks', '-rpath', '/Library/Frameworks', '-rpath', '/System/Library/Frameworks', ] ) if (sys.platform != 'darwin' and sys.platform != 'win32') or env['TOOLSET'] == 'mingw': arch_flags = ['-m32'] if env['ARCH'] == 'x86' else ['-m64'] env.Append(CCFLAGS=arch_flags, LINKFLAGS=arch_flags) env.VariantDir('$VARIANT', '$LIBTCOD_ROOT_DIR') env_libtcod = env.Clone() env_libtcod.Append(CPPDEFINES=['LIBTCOD_EXPORTS']) if not using_msvc: env_libtcod.Prepend(CFLAGS=['-ansi']) if sys.platform != 'darwin': env_libtcod.Append(LIBS=['SDL2']) if 'NO_OPENGL' not in env['CPPDEFINES']: if sys.platform == 'win32': env_libtcod.Append(LIBS=['opengl32']) elif sys.platform == 'darwin': env_libtcod.Append(LINKFLAGS=['-framework', 'OpenGL']) else: env_libtcod.Append(LIBS=['GL']) libtcod = env_libtcod.SharedLibrary( target='$VARIANT/libtcod', source=(env.Glob('$VARIANT/src/*.c*') + env.Glob('$VARIANT/src/*/*.c')), ) env_libtcod_gui = env.Clone() env_libtcod_gui.Append( CPPDEFINES=['LIBTCOD_GUI_EXPORTS'], LIBS=['libtcod' if sys.platform == 'win32' else 'tcod'], ) libtcod_gui = env_libtcod_gui.SharedLibrary( target='$VARIANT/libtcod-gui', source=Glob(env.subst('$VARIANT/src/gui/*.cpp')), ) env.Depends(libtcod_gui, libtcod) if sys.platform == 'darwin': env_libtcod.Append(LINKFLAGS=['-install_name', '@rpath/libtcod.dylib']) env_libtcod_gui.Append(LINKFLAGS=['-install_name', '@rpath/libtcod-gui.dylib']) lib_build = [libtcod, libtcod_gui] lib_install = env.Install('$INSTALL_DIR', lib_build) + sdl_install Alias("build_libtcod", lib_build) Alias("develop_libtcod", lib_build + lib_install) samples_builders = samples_factory() samples_installers = env.Install('$INSTALL_DIR', samples_builders) Alias("build_samples", samples_builders) Alias("develop_samples", samples_builders + samples_installers) package_files = ( lib_build + samples_builders + sdl_package + env.Glob('$VARIANT/*.md') + env.Glob('$VARIANT/*.txt') + env.Glob('$VARIANT/*.png') + env.Glob('$VARIANT/data/**/*.*') + env.Glob('$VARIANT/doc/**/*.*') + env.Glob('$VARIANT/include/*.h*') + env.Glob('$VARIANT/include/**/*.h*') + env.Glob('$VARIANT/lua/*.lua') + env.Glob('$VARIANT/python/*.py') + env.Glob('$VARIANT/python/**/*.py') + env.Glob('$VARIANT/python/**.pyproj') + env.Glob('$VARIANT/python/**.cfg') + env.Glob('$VARIANT/python/**.in') + env.Glob('$VARIANT/samples/*.c*') + env.Glob('$VARIANT/samples/**/*.c*') + env.Glob('$VARIANT/samples/**/*.h*') + env.Glob('$VARIANT/samples/**/*.png') + env.Glob('$VARIANT/samples/**/*.txt') ) if sys.platform == 'win32': zip = env.Zip('${DIST_NAME}.zip', package_files) else: env.Append(TARFLAGS = '-c -z') zip = env.Tar('${DIST_NAME}.tar.gz', package_files) Alias("dist", zip) Alias("build", ["build_samples", "build_libtcod"]) Alias("develop", ["develop_samples", "develop_libtcod"]) Default(None) Help(vars.GenerateHelpText(env)) libtcod-1.6.4+dfsg/build/scons/config.py000066400000000000000000000012361321276576200201410ustar00rootroot00000000000000 DEFINES = ['NDEBUG', 'TCOD_SDL2'] # MODE options are DEBUG, SIZE, PERFORMANCE, and RELEASE. DEBUG_GCC = { #'CFLAGS': ['-Wstrict-prototypes'], 'CCFLAGS': ['-Wall', '-g'], } DEBUG_MSVC = {'CCFLAGS': ['-W3', '-DEBUG']} SIZE_GCC = { 'CCFLAGS': ['-Wall', '-Os', '-flto'], 'LINKFLAGS': ['-Os', '-flto'], } SIZE_MSVC = { 'CCFLAGS': ['-W3', '-O1', '-GL', '-GS-'], 'LINKFLAGS': ['-LTCG'], } PERFORMANCE_GCC = { 'CCFLAGS': ['-Wall', '-O3', '-flto'], 'LINKFLAGS': ['-O3', '-flto'], } PERFORMANCE_MSVC = { 'CCFLAGS': ['-W3', '-O2', '-GL', '-GS-'], 'LINKFLAGS': ['-LTCG'], } RELEASE_GCC = PERFORMANCE_GCC RELEASE_MSVC = PERFORMANCE_MSVC libtcod-1.6.4+dfsg/include/000077500000000000000000000000001321276576200155175ustar00rootroot00000000000000libtcod-1.6.4+dfsg/include/bresenham.h000066400000000000000000000050761321276576200176440ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_BRESENHAM_H #define _TCOD_BRESENHAM_H #include "libtcod_portability.h" #ifdef __cplusplus extern "C" { #endif typedef bool (*TCOD_line_listener_t) (int x, int y); TCODLIB_API void TCOD_line_init(int xFrom, int yFrom, int xTo, int yTo); TCODLIB_API bool TCOD_line_step(int *xCur, int *yCur); /* advance one step. returns true if we reach destination */ /* atomic callback function. Stops when the callback returns false */ TCODLIB_API bool TCOD_line(int xFrom, int yFrom, int xTo, int yTo, TCOD_line_listener_t listener); /* thread-safe versions */ typedef struct { int stepx; int stepy; int e; int deltax; int deltay; int origx; int origy; int destx; int desty; } TCOD_bresenham_data_t; TCODLIB_API void TCOD_line_init_mt(int xFrom, int yFrom, int xTo, int yTo, TCOD_bresenham_data_t *data); TCODLIB_API bool TCOD_line_step_mt(int *xCur, int *yCur, TCOD_bresenham_data_t *data); TCODLIB_API bool TCOD_line_mt(int xFrom, int yFrom, int xTo, int yTo, TCOD_line_listener_t listener, TCOD_bresenham_data_t *data); #ifdef __cplusplus } #endif #endif libtcod-1.6.4+dfsg/include/bresenham.hpp000066400000000000000000000123441321276576200202000ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_BRESENHAM_HPP #define _TCOD_BRESENHAM_HPP #include "bresenham.h" class TCODLIB_API TCODLineListener { public : virtual bool putPoint(int x,int y) = 0; virtual ~TCODLineListener() {} }; class TCODLIB_API TCODLine { public : /** @PageName line @PageCategory Base toolkits @PageTitle Line drawing toolkit @PageDesc This toolkit is a very simple and lightweight implementation of the bresenham line drawing algorithm. It allows you to follow straight paths on your map very easily. @FuncTitle Initializing the line @FuncDesc First, you have to initialize the toolkit with your starting and ending coordinates. @Cpp static void TCODLine::init (int xFrom, int yFrom, int xTo, int yTo) @C void TCOD_line_init (int xFrom, int yFrom, int xTo, int yTo) @Py line_init (xFrom, yFrom, xTo, yTo) @C# static void TCODLine::init(int xFrom, int yFrom, int xTo, int yTo) @Lua tcod.line.init(xFrom,yFrom, xTo,yTo) @Param xFrom,yFrom Coordinates of the line's starting point. @Param xTo,yTo Coordinates of the line's ending point. */ static void init(int xFrom, int yFrom, int xTo, int yTo); /** @PageName line @FuncTitle Walking the line @FuncDesc You can then step through each cell with this function. It returns true when you reach the line's ending point. @Cpp static bool TCODLine::step (int * xCur, int * yCur) @C bool TCOD_line_step (int * xCur, int * yCur) @Py line_step () # returns x,y or None,None if finished @C# static bool TCODLine::step(ref int xCur, ref int yCur) @Lua tcod.line.step(x,y) -- returns lineEnd,x,y @Param xCur,yCur the coordinates of the next cell on the line are stored here when the function returns @CppEx // Going from point 5,8 to point 13,4 int x = 5, y = 8; TCODLine::init(x,y,13,4); do { // update cell x,y } while (!TCODLine::step(&x,&y)); @CEx int x = 5, y = 8; TCOD_line_init(x,y,13,4); do { // update cell x,y } while (!TCOD_line_step(&x,&y)); @PyEx libtcod.line_init(5,8,13,4) # update cell 5,8 x,y=libtcod.line_step() while (not x is None) : # update cell x,y x,y=libtcod.line_step() @LuaEx x=5 y=8 tcod.line.init(x,y,13,4) repeat -- update cell x,y lineEnd,x,y = tcod.line.step(x,y) until lineEnd */ static bool step(int *xCur, int *yCur); /** @PageName line @FuncTitle Callback-based function @FuncDesc The function returns false if the line has been interrupted by the callback (it returned false before the last point). @Cpp class TCODLIB_API TCODLineListener { virtual bool putPoint (int x, int y) = 0; }; static bool TCODLine::line (int xFrom, int yFrom, int xTo, int yTo, TCODLineListener * listener) @C typedef bool (*TCOD_line_listener_t) (int x, int y); bool TCOD_line(int xFrom, int yFrom, int xTo, int yTo, TCOD_line_listener_t listener) @Py def line_listener(x,y) : # ... line(xFrom, yFrom, xTo, yTo, listener) @C# static bool line(int xFrom, int yFrom, int xTo, int yTo, TCODLineListener listener) @Param xFrom,yFrom Coordinates of the line's starting point. @Param xTo,yTo Coordinates of the line's ending point. @Param listener Callback called for each line's point. The function stops if the callback returns false. @CppEx // Going from point 5,8 to point 13,4 class MyLineListener : public TCODLineListener { public: bool putPoint (int x,int y) { printf ("%d %d\n",x,y); return true; } }; MyLineListener myListener; TCODLine::line(5,8,13,4,&myListener); @CEx bool my_listener(int x,int y) { printf ("%d %d\n",x,y); return true; } TCOD_line_line(5,8,13,4,my_listener); @PyEx def my_listener(x,y): print x,y return True libtcod.line_line(5,8,13,4,my_listener) */ static bool line(int xFrom, int yFrom, int xTo, int yTo, TCODLineListener *listener); }; #endif libtcod-1.6.4+dfsg/include/bsp.h000066400000000000000000000067531321276576200164670ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_BSP_H #define _TCOD_BSP_H #include "libtcod_portability.h" #include "mersenne_types.h" #include "tree.h" #ifdef __cplusplus extern "C" { #endif typedef struct { TCOD_tree_t tree; /* pseudo oop : bsp inherit tree */ int x,y,w,h; /* node position & size */ int position; /* position of splitting */ uint8_t level; /* level in the tree */ bool horizontal; /* horizontal splitting ? */ } TCOD_bsp_t; typedef bool (*TCOD_bsp_callback_t)(TCOD_bsp_t *node, void *userData); TCODLIB_API TCOD_bsp_t *TCOD_bsp_new(void); TCODLIB_API TCOD_bsp_t *TCOD_bsp_new_with_size(int x,int y,int w, int h); TCODLIB_API void TCOD_bsp_delete(TCOD_bsp_t *node); TCODLIB_API TCOD_bsp_t * TCOD_bsp_left(TCOD_bsp_t *node); TCODLIB_API TCOD_bsp_t * TCOD_bsp_right(TCOD_bsp_t *node); TCODLIB_API TCOD_bsp_t * TCOD_bsp_father(TCOD_bsp_t *node); TCODLIB_API bool TCOD_bsp_is_leaf(TCOD_bsp_t *node); TCODLIB_API bool TCOD_bsp_traverse_pre_order(TCOD_bsp_t *node, TCOD_bsp_callback_t listener, void *userData); TCODLIB_API bool TCOD_bsp_traverse_in_order(TCOD_bsp_t *node, TCOD_bsp_callback_t listener, void *userData); TCODLIB_API bool TCOD_bsp_traverse_post_order(TCOD_bsp_t *node, TCOD_bsp_callback_t listener, void *userData); TCODLIB_API bool TCOD_bsp_traverse_level_order(TCOD_bsp_t *node, TCOD_bsp_callback_t listener, void *userData); TCODLIB_API bool TCOD_bsp_traverse_inverted_level_order(TCOD_bsp_t *node, TCOD_bsp_callback_t listener, void *userData); TCODLIB_API bool TCOD_bsp_contains(TCOD_bsp_t *node, int x, int y); TCODLIB_API TCOD_bsp_t * TCOD_bsp_find_node(TCOD_bsp_t *node, int x, int y); TCODLIB_API void TCOD_bsp_resize(TCOD_bsp_t *node, int x,int y, int w, int h); TCODLIB_API void TCOD_bsp_split_once(TCOD_bsp_t *node, bool horizontal, int position); TCODLIB_API void TCOD_bsp_split_recursive(TCOD_bsp_t *node, TCOD_random_t randomizer, int nb, int minHSize, int minVSize, float maxHRatio, float maxVRatio); TCODLIB_API void TCOD_bsp_remove_sons(TCOD_bsp_t *node); #ifdef __cplusplus } #endif #endif libtcod-1.6.4+dfsg/include/bsp.hpp000066400000000000000000000426161321276576200170250ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_BSP_HPP #define _TCOD_BSP_HPP #include "bsp.h" #include "list.hpp" #include "mersenne.hpp" #include "tree.hpp" class TCODBsp; class TCODLIB_API ITCODBspCallback { public : virtual ~ITCODBspCallback() {} virtual bool visitNode(TCODBsp *node, void *userData) = 0; }; /** @PageName bsp @PageCategory Roguelike toolkits @PageTitle BSP toolkit @PageDesc This toolkit allows one to create and manipulate 2D Binary Space Partition trees. They can be used to split a rectangular region into non overlapping sub-regions. */ class TCODLIB_API TCODBsp : public TCODTree { public : int x,y,w,h; // int position; // position of splitting bool horizontal; // horizontal splitting ? uint8_t level; // level in the tree /** @PageName bsp_init @PageFather bsp @PageTitle Creating a BSP tree @FuncTitle Creating the root node @FuncDesc First, you have to create the root node of the tree. This node encompasses the whole rectangular region. @Cpp TCODBsp::TCODBsp(int x,int y,int w, int h) @C TCOD_bsp_t *TCOD_bsp_new_with_size(int x,int y,int w, int h) @Py bsp_new_with_size(x,y,w, h) @C# TCODBsp::TCODBsp(int x, int y, int w, int h) @Param x,y,w,h Top left corner position and size of the rectangular region covered by the BSP tree. @CppEx TCODBsp *myBSP = new TCODBsp(0,0,50,50); @CEx TCOD_bsp_t *my_bsp=TCOD_bsp_new_with_size(0,0,50,50); @PyEx my_bsp=libtcod.bsp_new_with_size(0,0,50,50) */ TCODBsp() : level(0) {} TCODBsp(int x,int y,int w, int h) : x(x),y(y),w(w),h(h),level(0) {} /** @PageName bsp_init @FuncTitle Deleting a part of the tree @FuncDesc You can delete a part of the tree, releasing resources for all sub nodes with : @Cpp void TCODBsp::removeSons() @C void TCOD_bsp_remove_sons(TCOD_bsp_t *node) @Py bsp_remove_sons(node) @C# TCODBsp::removeSons() @Param node In the C version, the node reference. @CppEx TCODBsp *myBSP = new TCODBsp(0,0,50,50); // create a tree myBSP->splitRecursive(NULL,4,5,5,1.5f,1.5f); // clear it (keep only the root) myBSP->removeSons(); // and rebuild another random tree myBSP->splitRecursive(NULL,4,5,5,1.5f,1.5f); @CEx TCOD_bsp_t *my_bsp=TCOD_bsp_new_with_size(0,0,50,50); TCOD_bsp_split_recursive(my_bsp,NULL,4,5,5,1.5f,1.5f); TCOD_bsp_remove_sons(my_bsp); TCOD_bsp_split_recursive(my_bsp,NULL,4,5,5,1.5f,1.5f); @PyEx my_bsp=libtcod.bsp_new_with_size(0,0,50,50) libtcod.bsp_split_recursive(my_bsp,0,4,5,5,1.5,1.5) libtcod.bsp_remove_sons(my_bsp) libtcod.bsp_split_recursive(my_bsp,0,4,5,5,1.5,1.5) */ void removeSons(); /** @PageName bsp_init @FuncTitle deleting the tree @FuncDesc You can also completely delete the tree, including the root node to release every resource used : @Cpp void TCODBsp::~TCODBsp() @C void TCOD_bsp_delete(TCOD_bsp_t *node) @Py bsp_delete(node) @C# void TCODBsp::Dispose() @Param node In the C version, the node reference. @CppEx TCODBsp *myBSP = new TCODBsp(0,0,50,50); // create a tree myBSP->splitRecursive(NULL,4,5,5,1.5f,1.5f); // use the tree ... // delete the tree delete myBSP; @CEx TCOD_bsp_t *my_bsp=TCOD_bsp_new_with_size(0,0,50,50); TCOD_bsp_split_recursive(my_bsp,NULL,4,5,5,1.5f,1.5f); // use the tree ... TCOD_bsp_delete(my_bsp); @PyEx my_bsp=libtcod.bsp_new_with_size(0,0,50,50) libtcod.bsp_split_recursive(my_bsp,0,4,5,5,1.5,1.5) # use the tree ... libtcod.bsp_delete(my_bsp) */ virtual ~TCODBsp(); /** @PageName bsp_split @PageFather bsp @PageTitle Splitting the tree @FuncTitle Splitting a node once @FuncDesc Once you have the root node, you can split it into two smaller non-overlapping nodes. @Cpp void TCODBsp::splitOnce(bool horizontal, int position) @C void TCOD_bsp_split_once(TCOD_bsp_t *node, bool horizontal, int position) @Py bsp_split_once(node, horizontal, position) @C# void TCODBsp::splitOnce(bool horizontal, int position) @Param node In the C version, the root node created with TCOD_bsp_new_with_size, or a node obtained by splitting. @Param horizontal If true, the node will be split horizontally, else, vertically. @Param position Coordinate of the splitting position. If horizontal is true, x <= position < x+w Else, y <= position < y+h @CppEx TCODBsp *myBSP = new TCODBsp(0,0,50,50); myBSP->splitOnce(true,20); // horizontal split into two nodes : (0,0,50,20) and (0,20,50,30) @CEx TCOD_bsp_t *my_bsp=TCOD_bsp_new_with_size(0,0,50,50); TCOD_bsp_split_once(my_bsp,false,20); // vertical split into two nodes : (0,0,20,50) and (20,0,30,50) @PyEx my_bsp=libtcod.bsp_new_with_size(0,0,50,50) libtcod.bsp_split_once(my_bsp,False,20) # vertical split into two nodes : (0,0,20,50) and (20,0,30,50) */ void splitOnce(bool horizontal, int position); /** @PageName bsp_split @FuncTitle Recursively splitting a node @FuncDesc You can also recursively split the bsp. At each step, a random orientation (horizontal/vertical) and position are chosen : @Cpp void TCODBsp::splitRecursive(TCODRandom *randomizer, int nb, int minHSize, int minVSize, float maxHRatio, float maxVRatio); @C void TCOD_bsp_split_recursive(TCOD_bsp_t *node, TCOD_random_t randomizer, int nb, int minHSize, int minVSize, float maxHRatio, float maxVRatio) @Py bsp_split_recursive(node, randomizer, nb, minHSize, minVSize, maxHRatio, maxVRatio) @C# void TCODBsp::splitRecursive(TCODRandom randomizer, int nb, int minHSize, int minVSize, float maxHRatio, float maxVRatio) @Param node In the C version, the root node created with TCOD_bsp_new_with_size, or a node obtained by splitting. @Param randomizer The random number generator to use. Use NULL for the default one. @Param nb Number of recursion levels. @Param minHSize, minVSize minimum values of w and h for a node. A node is split only if the resulting sub-nodes are bigger than minHSize x minVSize @Param maxHRatio, maxVRation maximum values of w/h and h/w for a node. If a node does not conform, the splitting orientation is forced to reduce either the w/h or the h/w ratio. Use values near 1.0 to promote square nodes. @CppEx // Do a 4 levels BSP tree (the region is split into a maximum of 2*2*2*2 sub-regions). TCODBsp *myBSP = new TCODBsp(0,0,50,50); myBSP->splitRecursive(NULL,4,5,5,1.5f,1.5f); @CEx TCOD_bsp_t *my_bsp=TCOD_bsp_new_with_size(0,0,50,50); TCOD_bsp_split_recursive(my_bsp,NULL,4,5,5,1.5f,1.5f); @PyEx my_bsp=libtcod.bsp_new_with_size(0,0,50,50) libtcod.bsp_split_recursive(my_bsp,0,4,5,5,1.5,1.5) */ void splitRecursive(TCODRandom *randomizer, int nb, int minHSize, int minVSize, float maxHRatio, float maxVRatio); /** @PageName bsp_resize @PageTitle Resizing a tree @PageFather bsp @FuncDesc This operation resets the size of the tree nodes without changing the splitting data (orientation/position). It should be called with the initial region size or a bigger size, else some splitting position may be out of the region. You can use it if you changed the nodes size and position while using the BSP tree, which happens typically when you use the tree to build a dungeon. You create rooms inside the tree leafs, then shrink the leaf to fit the room size. Calling resize on the root node with the original region size allows you to reset all nodes to their original size. @Cpp void TCODBsp::resize(int x,int y, int w, int h) @C void TCOD_bsp_resize(TCOD_bsp_t *node, int x,int y, int w, int h) @Py bsp_resize(node, x,y, w, h) @C# void TCODBsp::resize(int x, int y, int w, int h) @Param node In the C version, the root node created with TCOD_bsp_new_with_size, or a node obtained by splitting. @Param x,y,w,h New position and size of the node. The original rectangular area covered by the node should be included in the new one to ensure that every splitting edge stay inside its node. @CppEx // We create a BSP, do some processing that will modify the x,y,w,h fields of the tree nodes, then reset all the nodes to their original size. TCODBsp *myBSP = new TCODBsp(0,0,50,50); myBSP->splitRecursive(NULL,4,5,5,1.5f,1.5f); // ... do something with the tree here myBSP->resize(0,0,50,50); @CEx TCOD_bsp_t *my_bsp=TCOD_bsp_new_with_size(0,0,50,50); TCOD_bsp_split_recursive(my_bsp,NULL,4,5,5,1.5f,1.5f); // ... do something with the tree here TCOD_bsp_resize(my_bsp,0,0,50,50); @PyEx my_bsp=libtcod.bsp_new_with_size(0,0,50,50) libtcod.bsp_split_recursive(my_bsp,0,4,5,5,1.5,1.5) # ... do something with the tree here libtcod.bsp_resize(my_bsp,0,0,50,50) */ void resize(int x,int y, int w, int h); /** @PageName bsp_read @PageFather bsp @PageTitle Reading information from the tree @FuncDesc Once you have built a BSP tree, you can retrieve information from any node. The node gives you free access to its fields : @Cpp class TCODBsp { public : int x,y,w,h; // int position; // position of splitting bool horizontal; // horizontal splitting ? uint8_t level; // level in the tree ... } @C typedef struct { int x,y,w,h; int position; bool horizontal; uint8_t level; ... } TCOD_bsp_t; @C# class TCODBsp { public int x { get; set; } public int y { get; set; } public int h { get; set; } public int w { get; set; } public int position { get; set; } public bool horizontal { get; set; } public byte level { get; set; } } @Param x,y,w,h Rectangular region covered by this node. @Param position If this node is not a leaf, splitting position. @Param horizontal If this node is not a leaf, splitting orientation. @Param level Level in the BSP tree (0 for the root, 1 for the root's sons, ...). */ /** @PageName bsp_read @FuncTitle Navigate in the tree @FuncDesc You can navigate from a node to its sons or its parent using one of those functions. Each function returns NULL if the corresponding node does not exists (if the node is not split for getLeft and getRight, and if the node is the root node for getFather). @Cpp TCODBsp *TCODBsp::getLeft() const TCODBsp *TCODBsp::getRight() const TCODBsp *TCODBsp::getFather() const @C TCOD_bsp_t * TCOD_bsp_left(TCOD_bsp_t *node) TCOD_bsp_t * TCOD_bsp_right(TCOD_bsp_t *node) TCOD_bsp_t * TCOD_bsp_father(TCOD_bsp_t *node) @Py bsp_left(node) bsp_right(node) bsp_father(node) @C# TCODBsp TCODBsp::getLeft() TCODBsp TCODBsp::getRight() TCODBsp TCODBsp::getFather() @Param node In the C version, the node reference. */ TCODBsp *getLeft() const { return (TCODBsp *)sons; } TCODBsp *getRight() const { return sons ? (TCODBsp *)(sons->next) : NULL; } TCODBsp *getFather() const { return (TCODBsp *)father; } /** @PageName bsp_read @FuncTitle Checking if a node is a leaf @FuncDesc You can know if a node is a leaf (not split, no sons) with this function : @Cpp bool TCODBsp::isLeaf() const @C bool TCOD_bsp_is_leaf(TCOD_bsp_t *node) @Py bsp_is_leaf(node) @C# bool TCODBsp::isLeaf() */ bool isLeaf() const { return sons == NULL ; } /** @PageName bsp_read @FuncTitle Check if a cell is inside a node @FuncDesc You can check if a map cell is inside a node. @Cpp bool TCODBsp::contains(int cx, int cy) const @C bool TCOD_bsp_contains(TCOD_bsp_t *node, int cx, int cy) @Py bsp_contains(node, cx, cy) @C# bool TCODBsp::contains(int x, int y) @Param node In the C version, the node reference. @Param cx,cy Map cell coordinates. */ bool contains(int x, int y) const; /** @PageName bsp_read @FuncTitle Getting the node containing a cell @FuncDesc You can search the tree for the smallest node containing a map cell. If the cell is outside the tree, the function returns NULL : @Cpp TCODBsp *TCODBsp::findNode(int cx, int cy) @C TCOD_bsp_t * TCOD_bsp_find_node(TCOD_bsp_t *node, int cx, int cy) @Py bsp_find_node(node, cx, cy) @C# TCODBsp TCODBsp::findNode(int x, int y) @Param node In the C version, the node reference. @Param cx,cy Map cell coordinates. */ TCODBsp *findNode(int x, int y); /** @PageName bsp_traverse @PageFather bsp @PageTitle Traversing the tree @FuncDesc You can scan all the nodes of the tree and have a custom function called back for each node. Each traversal function returns false if the traversal has been interrupted (a callback returned false). * Pre-order : the callback is called for the current node, then for the left son, then for the right son. * In-order : the callback is called for the left son, then for current node, then for the right son. * Post-order : the callback is called for the left son, then for the right son, then for the current node. * Level-order : the callback is called for the nodes level by level, from left to right. * Inverted level-order : the callback is called in the exact inverse order as Level-order.
Pre orderIn orderPost orderLevel orderInverted level
order
@Cpp class ITCODBspCallback { public : virtual bool visitNode(TCODBsp *node, void *userData) = 0; }; bool TCODBsp::traversePreOrder(ITCODBspCallback *callback, void *userData) bool TCODBsp::traverseInOrder(ITCODBspCallback *callback, void *userData) bool TCODBsp::traversePostOrder(ITCODBspCallback *callback, void *userData) bool TCODBsp::traverseLevelOrder(ITCODBspCallback *callback, void *userData) bool TCODBsp::traverseInvertedLevelOrder(ITCODBspCallback *callback, void *userData) @C typedef bool (*TCOD_bsp_callback_t)(TCOD_bsp_t *node, void *userData) bool TCOD_bsp_traverse_pre_order(TCOD_bsp_t *node, TCOD_bsp_callback_t callback, void *userData) bool TCOD_bsp_traverse_in_order(TCOD_bsp_t *node, TCOD_bsp_callback_t callback, void *userData) bool TCOD_bsp_traverse_post_order(TCOD_bsp_t *node, TCOD_bsp_callback_t callback, void *userData) bool TCOD_bsp_traverse_level_order(TCOD_bsp_t *node, TCOD_bsp_callback_t callback, void *userData) bool TCOD_bsp_traverse_inverted_level_order(TCOD_bsp_t *node, TCOD_bsp_callback_t callback, void *userData) @Py def bsp_callback(node, userData) : # ... bsp_traverse_pre_order(node, callback, userData=0) bsp_traverse_in_order(node, callback, userData=0) bsp_traverse_post_order(node, callback, userData=0) bsp_traverse_level_order(node, callback, userData=0) bsp_traverse_inverted_level_order(node, callback, userData=0) @C# bool TCODBsp::traversePreOrder(ITCODBspCallback callback) bool TCODBsp::traverseInOrder(ITCODBspCallback callback) bool TCODBsp::traversePostOrder(ITCODBspCallback callback) bool TCODBsp::traverseLevelOrder(ITCODBspCallback callback) bool TCODBsp::traverseInvertedLevelOrder(ITCODBspCallback callback) @Param node In the C version, the node reference (generally, the root node). @Param callback The function to call for each node. It receives the current node and the custom data as parameters If it returns false, the traversal is interrupted. @Param userData Custom data to pass to the callback. @CppEx class MyCallback : public ITCODBspCallback { public : bool visitNode(TCODBsp *node, void *userData) { printf("node pos %dx%d size %dx%d level %d\n",node->x,node->y,node->w,node->h,node->level); return true; } }; myBSP->traversePostOrder(new MyListener(),NULL); @CEx bool my_callback(TCOD_bsp_t *node, void *userData) { printf("node pos %dx%d size %dx%d level %d\n",node->x,node->y,node->w,node->h,node->level); return true; } TCOD_bsp_traverse_post_order(my_bsp,my_callback,NULL); @PyEx def my_callback(node, userData) : print "node pos %dx%d size %dx%d level %d"%(node.x,node.y,node.w,node.h,node.level)) return True libtcod.bsp_traverse_post_order(my_bsp,my_callback) */ bool traversePreOrder(ITCODBspCallback *listener, void *userData); bool traverseInOrder(ITCODBspCallback *listener, void *userData); bool traversePostOrder(ITCODBspCallback *listener, void *userData); bool traverseLevelOrder(ITCODBspCallback *listener, void *userData); bool traverseInvertedLevelOrder(ITCODBspCallback *listener, void *userData); protected : TCODBsp(TCODBsp *father, bool left); }; #endif libtcod-1.6.4+dfsg/include/color.h000066400000000000000000000361461321276576200170200ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_COLOR_H #define _TCOD_COLOR_H #include "libtcod_portability.h" #ifdef __cplusplus extern "C" { #endif typedef struct { uint8_t r,g,b; } TCOD_color_t; /* constructors */ TCODLIB_API TCOD_color_t TCOD_color_RGB(uint8_t r, uint8_t g, uint8_t b); TCODLIB_API TCOD_color_t TCOD_color_HSV(float h, float s, float v); /* basic operations */ TCODLIB_API bool TCOD_color_equals (TCOD_color_t c1, TCOD_color_t c2); TCODLIB_API TCOD_color_t TCOD_color_add (TCOD_color_t c1, TCOD_color_t c2); TCODLIB_API TCOD_color_t TCOD_color_subtract (TCOD_color_t c1, TCOD_color_t c2); TCODLIB_API TCOD_color_t TCOD_color_multiply (TCOD_color_t c1, TCOD_color_t c2); TCODLIB_API TCOD_color_t TCOD_color_multiply_scalar (TCOD_color_t c1, float value); TCODLIB_API TCOD_color_t TCOD_color_lerp (TCOD_color_t c1, TCOD_color_t c2, float coef); /* HSV transformations */ TCODLIB_API void TCOD_color_set_HSV (TCOD_color_t *c,float h, float s, float v); TCODLIB_API void TCOD_color_get_HSV (TCOD_color_t c,float * h, float * s, float * v); TCODLIB_API float TCOD_color_get_hue (TCOD_color_t c); TCODLIB_API void TCOD_color_set_hue (TCOD_color_t *c, float h); TCODLIB_API float TCOD_color_get_saturation (TCOD_color_t c); TCODLIB_API void TCOD_color_set_saturation (TCOD_color_t *c, float s); TCODLIB_API float TCOD_color_get_value (TCOD_color_t c); TCODLIB_API void TCOD_color_set_value (TCOD_color_t *c, float v); TCODLIB_API void TCOD_color_shift_hue (TCOD_color_t *c, float hshift); TCODLIB_API void TCOD_color_scale_HSV (TCOD_color_t *c, float scoef, float vcoef); /* color map */ TCODLIB_API void TCOD_color_gen_map(TCOD_color_t *map, int nb_key, TCOD_color_t const *key_color, int const *key_index); /* color names */ enum { TCOD_COLOR_RED, TCOD_COLOR_FLAME, TCOD_COLOR_ORANGE, TCOD_COLOR_AMBER, TCOD_COLOR_YELLOW, TCOD_COLOR_LIME, TCOD_COLOR_CHARTREUSE, TCOD_COLOR_GREEN, TCOD_COLOR_SEA, TCOD_COLOR_TURQUOISE, TCOD_COLOR_CYAN, TCOD_COLOR_SKY, TCOD_COLOR_AZURE, TCOD_COLOR_BLUE, TCOD_COLOR_HAN, TCOD_COLOR_VIOLET, TCOD_COLOR_PURPLE, TCOD_COLOR_FUCHSIA, TCOD_COLOR_MAGENTA, TCOD_COLOR_PINK, TCOD_COLOR_CRIMSON, TCOD_COLOR_NB }; /* color levels */ enum { TCOD_COLOR_DESATURATED, TCOD_COLOR_LIGHTEST, TCOD_COLOR_LIGHTER, TCOD_COLOR_LIGHT, TCOD_COLOR_NORMAL, TCOD_COLOR_DARK, TCOD_COLOR_DARKER, TCOD_COLOR_DARKEST, TCOD_COLOR_LEVELS }; /* color array */ extern TCODLIB_API const TCOD_color_t TCOD_colors[TCOD_COLOR_NB][TCOD_COLOR_LEVELS]; /* grey levels */ extern TCODLIB_API const TCOD_color_t TCOD_black; extern TCODLIB_API const TCOD_color_t TCOD_darkest_grey; extern TCODLIB_API const TCOD_color_t TCOD_darker_grey; extern TCODLIB_API const TCOD_color_t TCOD_dark_grey; extern TCODLIB_API const TCOD_color_t TCOD_grey; extern TCODLIB_API const TCOD_color_t TCOD_light_grey; extern TCODLIB_API const TCOD_color_t TCOD_lighter_grey; extern TCODLIB_API const TCOD_color_t TCOD_lightest_grey; extern TCODLIB_API const TCOD_color_t TCOD_darkest_gray; extern TCODLIB_API const TCOD_color_t TCOD_darker_gray; extern TCODLIB_API const TCOD_color_t TCOD_dark_gray; extern TCODLIB_API const TCOD_color_t TCOD_gray; extern TCODLIB_API const TCOD_color_t TCOD_light_gray; extern TCODLIB_API const TCOD_color_t TCOD_lighter_gray; extern TCODLIB_API const TCOD_color_t TCOD_lightest_gray; extern TCODLIB_API const TCOD_color_t TCOD_white; /* sepia */ extern TCODLIB_API const TCOD_color_t TCOD_darkest_sepia; extern TCODLIB_API const TCOD_color_t TCOD_darker_sepia; extern TCODLIB_API const TCOD_color_t TCOD_dark_sepia; extern TCODLIB_API const TCOD_color_t TCOD_sepia; extern TCODLIB_API const TCOD_color_t TCOD_light_sepia; extern TCODLIB_API const TCOD_color_t TCOD_lighter_sepia; extern TCODLIB_API const TCOD_color_t TCOD_lightest_sepia; /* standard colors */ extern TCODLIB_API const TCOD_color_t TCOD_red; extern TCODLIB_API const TCOD_color_t TCOD_flame; extern TCODLIB_API const TCOD_color_t TCOD_orange; extern TCODLIB_API const TCOD_color_t TCOD_amber; extern TCODLIB_API const TCOD_color_t TCOD_yellow; extern TCODLIB_API const TCOD_color_t TCOD_lime; extern TCODLIB_API const TCOD_color_t TCOD_chartreuse; extern TCODLIB_API const TCOD_color_t TCOD_green; extern TCODLIB_API const TCOD_color_t TCOD_sea; extern TCODLIB_API const TCOD_color_t TCOD_turquoise; extern TCODLIB_API const TCOD_color_t TCOD_cyan; extern TCODLIB_API const TCOD_color_t TCOD_sky; extern TCODLIB_API const TCOD_color_t TCOD_azure; extern TCODLIB_API const TCOD_color_t TCOD_blue; extern TCODLIB_API const TCOD_color_t TCOD_han; extern TCODLIB_API const TCOD_color_t TCOD_violet; extern TCODLIB_API const TCOD_color_t TCOD_purple; extern TCODLIB_API const TCOD_color_t TCOD_fuchsia; extern TCODLIB_API const TCOD_color_t TCOD_magenta; extern TCODLIB_API const TCOD_color_t TCOD_pink; extern TCODLIB_API const TCOD_color_t TCOD_crimson; /* dark colors */ extern TCODLIB_API const TCOD_color_t TCOD_dark_red; extern TCODLIB_API const TCOD_color_t TCOD_dark_flame; extern TCODLIB_API const TCOD_color_t TCOD_dark_orange; extern TCODLIB_API const TCOD_color_t TCOD_dark_amber; extern TCODLIB_API const TCOD_color_t TCOD_dark_yellow; extern TCODLIB_API const TCOD_color_t TCOD_dark_lime; extern TCODLIB_API const TCOD_color_t TCOD_dark_chartreuse; extern TCODLIB_API const TCOD_color_t TCOD_dark_green; extern TCODLIB_API const TCOD_color_t TCOD_dark_sea; extern TCODLIB_API const TCOD_color_t TCOD_dark_turquoise; extern TCODLIB_API const TCOD_color_t TCOD_dark_cyan; extern TCODLIB_API const TCOD_color_t TCOD_dark_sky; extern TCODLIB_API const TCOD_color_t TCOD_dark_azure; extern TCODLIB_API const TCOD_color_t TCOD_dark_blue; extern TCODLIB_API const TCOD_color_t TCOD_dark_han; extern TCODLIB_API const TCOD_color_t TCOD_dark_violet; extern TCODLIB_API const TCOD_color_t TCOD_dark_purple; extern TCODLIB_API const TCOD_color_t TCOD_dark_fuchsia; extern TCODLIB_API const TCOD_color_t TCOD_dark_magenta; extern TCODLIB_API const TCOD_color_t TCOD_dark_pink; extern TCODLIB_API const TCOD_color_t TCOD_dark_crimson; /* darker colors */ extern TCODLIB_API const TCOD_color_t TCOD_darker_red; extern TCODLIB_API const TCOD_color_t TCOD_darker_flame; extern TCODLIB_API const TCOD_color_t TCOD_darker_orange; extern TCODLIB_API const TCOD_color_t TCOD_darker_amber; extern TCODLIB_API const TCOD_color_t TCOD_darker_yellow; extern TCODLIB_API const TCOD_color_t TCOD_darker_lime; extern TCODLIB_API const TCOD_color_t TCOD_darker_chartreuse; extern TCODLIB_API const TCOD_color_t TCOD_darker_green; extern TCODLIB_API const TCOD_color_t TCOD_darker_sea; extern TCODLIB_API const TCOD_color_t TCOD_darker_turquoise; extern TCODLIB_API const TCOD_color_t TCOD_darker_cyan; extern TCODLIB_API const TCOD_color_t TCOD_darker_sky; extern TCODLIB_API const TCOD_color_t TCOD_darker_azure; extern TCODLIB_API const TCOD_color_t TCOD_darker_blue; extern TCODLIB_API const TCOD_color_t TCOD_darker_han; extern TCODLIB_API const TCOD_color_t TCOD_darker_violet; extern TCODLIB_API const TCOD_color_t TCOD_darker_purple; extern TCODLIB_API const TCOD_color_t TCOD_darker_fuchsia; extern TCODLIB_API const TCOD_color_t TCOD_darker_magenta; extern TCODLIB_API const TCOD_color_t TCOD_darker_pink; extern TCODLIB_API const TCOD_color_t TCOD_darker_crimson; /* darkest colors */ extern TCODLIB_API const TCOD_color_t TCOD_darkest_red; extern TCODLIB_API const TCOD_color_t TCOD_darkest_flame; extern TCODLIB_API const TCOD_color_t TCOD_darkest_orange; extern TCODLIB_API const TCOD_color_t TCOD_darkest_amber; extern TCODLIB_API const TCOD_color_t TCOD_darkest_yellow; extern TCODLIB_API const TCOD_color_t TCOD_darkest_lime; extern TCODLIB_API const TCOD_color_t TCOD_darkest_chartreuse; extern TCODLIB_API const TCOD_color_t TCOD_darkest_green; extern TCODLIB_API const TCOD_color_t TCOD_darkest_sea; extern TCODLIB_API const TCOD_color_t TCOD_darkest_turquoise; extern TCODLIB_API const TCOD_color_t TCOD_darkest_cyan; extern TCODLIB_API const TCOD_color_t TCOD_darkest_sky; extern TCODLIB_API const TCOD_color_t TCOD_darkest_azure; extern TCODLIB_API const TCOD_color_t TCOD_darkest_blue; extern TCODLIB_API const TCOD_color_t TCOD_darkest_han; extern TCODLIB_API const TCOD_color_t TCOD_darkest_violet; extern TCODLIB_API const TCOD_color_t TCOD_darkest_purple; extern TCODLIB_API const TCOD_color_t TCOD_darkest_fuchsia; extern TCODLIB_API const TCOD_color_t TCOD_darkest_magenta; extern TCODLIB_API const TCOD_color_t TCOD_darkest_pink; extern TCODLIB_API const TCOD_color_t TCOD_darkest_crimson; /* light colors */ extern TCODLIB_API const TCOD_color_t TCOD_light_red; extern TCODLIB_API const TCOD_color_t TCOD_light_flame; extern TCODLIB_API const TCOD_color_t TCOD_light_orange; extern TCODLIB_API const TCOD_color_t TCOD_light_amber; extern TCODLIB_API const TCOD_color_t TCOD_light_yellow; extern TCODLIB_API const TCOD_color_t TCOD_light_lime; extern TCODLIB_API const TCOD_color_t TCOD_light_chartreuse; extern TCODLIB_API const TCOD_color_t TCOD_light_green; extern TCODLIB_API const TCOD_color_t TCOD_light_sea; extern TCODLIB_API const TCOD_color_t TCOD_light_turquoise; extern TCODLIB_API const TCOD_color_t TCOD_light_cyan; extern TCODLIB_API const TCOD_color_t TCOD_light_sky; extern TCODLIB_API const TCOD_color_t TCOD_light_azure; extern TCODLIB_API const TCOD_color_t TCOD_light_blue; extern TCODLIB_API const TCOD_color_t TCOD_light_han; extern TCODLIB_API const TCOD_color_t TCOD_light_violet; extern TCODLIB_API const TCOD_color_t TCOD_light_purple; extern TCODLIB_API const TCOD_color_t TCOD_light_fuchsia; extern TCODLIB_API const TCOD_color_t TCOD_light_magenta; extern TCODLIB_API const TCOD_color_t TCOD_light_pink; extern TCODLIB_API const TCOD_color_t TCOD_light_crimson; /* lighter colors */ extern TCODLIB_API const TCOD_color_t TCOD_lighter_red; extern TCODLIB_API const TCOD_color_t TCOD_lighter_flame; extern TCODLIB_API const TCOD_color_t TCOD_lighter_orange; extern TCODLIB_API const TCOD_color_t TCOD_lighter_amber; extern TCODLIB_API const TCOD_color_t TCOD_lighter_yellow; extern TCODLIB_API const TCOD_color_t TCOD_lighter_lime; extern TCODLIB_API const TCOD_color_t TCOD_lighter_chartreuse; extern TCODLIB_API const TCOD_color_t TCOD_lighter_green; extern TCODLIB_API const TCOD_color_t TCOD_lighter_sea; extern TCODLIB_API const TCOD_color_t TCOD_lighter_turquoise; extern TCODLIB_API const TCOD_color_t TCOD_lighter_cyan; extern TCODLIB_API const TCOD_color_t TCOD_lighter_sky; extern TCODLIB_API const TCOD_color_t TCOD_lighter_azure; extern TCODLIB_API const TCOD_color_t TCOD_lighter_blue; extern TCODLIB_API const TCOD_color_t TCOD_lighter_han; extern TCODLIB_API const TCOD_color_t TCOD_lighter_violet; extern TCODLIB_API const TCOD_color_t TCOD_lighter_purple; extern TCODLIB_API const TCOD_color_t TCOD_lighter_fuchsia; extern TCODLIB_API const TCOD_color_t TCOD_lighter_magenta; extern TCODLIB_API const TCOD_color_t TCOD_lighter_pink; extern TCODLIB_API const TCOD_color_t TCOD_lighter_crimson; /* lightest colors */ extern TCODLIB_API const TCOD_color_t TCOD_lightest_red; extern TCODLIB_API const TCOD_color_t TCOD_lightest_flame; extern TCODLIB_API const TCOD_color_t TCOD_lightest_orange; extern TCODLIB_API const TCOD_color_t TCOD_lightest_amber; extern TCODLIB_API const TCOD_color_t TCOD_lightest_yellow; extern TCODLIB_API const TCOD_color_t TCOD_lightest_lime; extern TCODLIB_API const TCOD_color_t TCOD_lightest_chartreuse; extern TCODLIB_API const TCOD_color_t TCOD_lightest_green; extern TCODLIB_API const TCOD_color_t TCOD_lightest_sea; extern TCODLIB_API const TCOD_color_t TCOD_lightest_turquoise; extern TCODLIB_API const TCOD_color_t TCOD_lightest_cyan; extern TCODLIB_API const TCOD_color_t TCOD_lightest_sky; extern TCODLIB_API const TCOD_color_t TCOD_lightest_azure; extern TCODLIB_API const TCOD_color_t TCOD_lightest_blue; extern TCODLIB_API const TCOD_color_t TCOD_lightest_han; extern TCODLIB_API const TCOD_color_t TCOD_lightest_violet; extern TCODLIB_API const TCOD_color_t TCOD_lightest_purple; extern TCODLIB_API const TCOD_color_t TCOD_lightest_fuchsia; extern TCODLIB_API const TCOD_color_t TCOD_lightest_magenta; extern TCODLIB_API const TCOD_color_t TCOD_lightest_pink; extern TCODLIB_API const TCOD_color_t TCOD_lightest_crimson; /* desaturated */ extern TCODLIB_API const TCOD_color_t TCOD_desaturated_red; extern TCODLIB_API const TCOD_color_t TCOD_desaturated_flame; extern TCODLIB_API const TCOD_color_t TCOD_desaturated_orange; extern TCODLIB_API const TCOD_color_t TCOD_desaturated_amber; extern TCODLIB_API const TCOD_color_t TCOD_desaturated_yellow; extern TCODLIB_API const TCOD_color_t TCOD_desaturated_lime; extern TCODLIB_API const TCOD_color_t TCOD_desaturated_chartreuse; extern TCODLIB_API const TCOD_color_t TCOD_desaturated_green; extern TCODLIB_API const TCOD_color_t TCOD_desaturated_sea; extern TCODLIB_API const TCOD_color_t TCOD_desaturated_turquoise; extern TCODLIB_API const TCOD_color_t TCOD_desaturated_cyan; extern TCODLIB_API const TCOD_color_t TCOD_desaturated_sky; extern TCODLIB_API const TCOD_color_t TCOD_desaturated_azure; extern TCODLIB_API const TCOD_color_t TCOD_desaturated_blue; extern TCODLIB_API const TCOD_color_t TCOD_desaturated_han; extern TCODLIB_API const TCOD_color_t TCOD_desaturated_violet; extern TCODLIB_API const TCOD_color_t TCOD_desaturated_purple; extern TCODLIB_API const TCOD_color_t TCOD_desaturated_fuchsia; extern TCODLIB_API const TCOD_color_t TCOD_desaturated_magenta; extern TCODLIB_API const TCOD_color_t TCOD_desaturated_pink; extern TCODLIB_API const TCOD_color_t TCOD_desaturated_crimson; /* metallic */ extern TCODLIB_API const TCOD_color_t TCOD_brass; extern TCODLIB_API const TCOD_color_t TCOD_copper; extern TCODLIB_API const TCOD_color_t TCOD_gold; extern TCODLIB_API const TCOD_color_t TCOD_silver; /* miscellaneous */ extern TCODLIB_API const TCOD_color_t TCOD_celadon; extern TCODLIB_API const TCOD_color_t TCOD_peach; #ifdef __cplusplus } #endif #endif libtcod-1.6.4+dfsg/include/color.hpp000066400000000000000000000642771321276576200173660ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_COLOR_HPP #define _TCOD_COLOR_HPP #include "color.h" #include "libtcod_utility.h" // color constants uses to generate @ColorTable /** @ColorCategory STANDARD COLORS @Color red 255,0,0 @Color flame 255,63,0 @Color orange 255,127,0 @Color amber 255,191,0 @Color yellow 255,255,0, @Color lime 191,255,0 @Color chartreuse 127,255,0 @Color green 0,255,0 @Color sea 0,255,127 @Color turquoise 0,255,191 @Color cyan 0,255,255 @Color sky 0,191,255 @Color azure 0,127,255 @Color blue 0,0,255 @Color han 63,0,255 @Color violet 127,0,255 @Color purple 191,0,255 @Color fuchsia 255,0,255 @Color magenta 255,0,191 @Color pink 255,0,127 @Color crimson 255,0,63 @ColorCategory METALLIC COLORS @Color brass 191,151,96 @Color copper 196,136,124 @Color gold 229,191,0 @Color silver 203,203,203 @ColorCategory MISCELLANEOUS COLORS @Color celadon 172,255,175 @Color peach 255,159,127 @ColorCategory GREYSCALE & SEPIA @Color grey 127,127,127 @Color sepia 127,101,63 @ColorCategory BLACK AND WHITE @Color black 0,0,0 @Color white 255,255,255 */ /** @PageName color @PageCategory Core @PageTitle Colors @PageDesc The Doryen library uses 32bits colors. Thus, your OS desktop must use 32bits colors. A color is defined by its red, green and blue component between 0 and 255. You can use the following predefined colors (hover over a color to see its full name and R,G,B values): @ColorTable @CppEx TCODColor::desaturatedRed TCODColor::lightestRed TCODColor::lighterRed TCODColor::lightRed TCODColor::red TCODColor::darkRed TCODColor::darkerRed TCODColor::darkestRed @CEx TCOD_desaturated_red TCOD_lightest_red TCOD_lighter_red TCOD_light_red TCOD_red TCOD_dark_red TCOD_darker_red TCOD_darkest_red @PyEx libtcod.desaturated_red libtcod.lightest_red libtcod.lighter_red libtcod.light_red libtcod.red libtcod.dark_red libtcod.darker_red libtcod.darkest_red @C#Ex TCODColor::desaturatedRed TCODColor::lightestRed TCODColor::lighterRed TCODColor::lightRed TCODColor::red TCODColor::darkRed TCODColor::darkerRed TCODColor::darkestRed @LuaEx tcod.color.desaturatedRed tcod.color.lightestRed tcod.color.lighterRed tcod.color.lightRed tcod.color.red tcod.color.darkRed tcod.color.darkerRed tcod.color.darkestRed */ class TCODLIB_API TCODColor { public : uint8_t r,g,b; TCODColor() : r(0),g(0),b(0) {} /** @PageName color @FuncTitle Create your own colors @FuncDesc You can create your own colours using a set of constructors, both for RGB and HSV values. @CppEx TCODColor myColor(24,64,255); //RGB TCODColor myOtherColor(321.0f,0.7f,1.0f); //HSV @CEx TCOD_color_t my_color={24,64,255}; /* RGB */ TCOD_color_t my_other_color = TCOD_color_RGB(24,64,255); /* RGB too */ TCOD_color_t my_yet_another_color = TCOD_color_HSV(321.0f,0.7f,1.0f); /* HSV */ @PyEx my_color=libtcod.Color(24,64,255) @C#Ex TCODColor myColor = new TCODColor(24,64,255); //RGB TCODColor myColor = new TCODColor(321.0f,0.7f,1.0f); //HSV @LuaEx myColor = tcod.Color(24,24,255) */ TCODColor(uint8_t r, uint8_t g, uint8_t b): r(r), g(g), b(b) {} TCODColor(int r, int g, int b): r(r), g(g), b(b) {} TCODColor(const TCOD_color_t &col): r(col.r), g(col.g), b(col.b) {} TCODColor(float h, float s, float v); /** @PageName color @FuncTitle Compare two colors @CppEx if (myColor == TCODColor::yellow) { ... } if (myColor != TCODColor::white) { ... } @CEx if (TCOD_color_equals(my_color,TCOD_yellow)) { ... } if (!TCOD_color_equals(my_color,TCOD_white)) { ... } @PyEx if my_color == libtcod.yellow : ... if my_color != litbcod.white : ... @C#Ex if (myColor.Equal(TCODColor.yellow)) { ... } if (myColor.NotEqual(TCODColor.white)) { ... } @LuaEx if myColor == tcod.color.yellow then ... end */ bool operator == (const TCODColor & c) const { return (c.r == r && c.g == g && c.b == b); } bool operator != (const TCODColor & c) const { return (c.r != r || c.g != g || c.b != b); } /** @PageName color @FuncTitle Multiply two colors @FuncDesc c1 = c2 * c3 => c1.r = c2.r * c3.r / 255 c1.g = c2.g * c3.g / 255 c1.b = c2.b * c3.b / 255 darkishRed = darkGrey * red
@CppEx TCODColor myDarkishRed = TCODColor::darkGrey * TCODColor::lightRed; @CEx TCOD_color_t my_darkish_red = TCOD_color_multiply(TCOD_dark_grey, TCOD_light_red); @PyEx my_darkish_red = libtcod.dark_grey * libtcod.light_red @C#Ex TCODColor myDarkishRed = TCODColor.darkGrey.Multiply(TCODColor.lightRed); @LuaEx myDarkishRed = tcod.color.darkGrey * tcod.color.lightRed */ TCODColor operator * (const TCODColor & a) const { TCODColor ret; ret.r=(uint8_t)(((int)r)*a.r/255); ret.g=(uint8_t)(((int)g)*a.g/255); ret.b=(uint8_t)(((int)b)*a.b/255); return ret; } /** @PageName color @FuncTitle Multiply a color by a float @FuncDesc c1 = c2 * v => c1.r = CLAMP(0, 255, c2.r * v) c1.g = CLAMP(0, 255, c2.g * v) c1.b = CLAMP(0, 255, c2.b * v) darkishRed = red * 0.5
@CppEx TCODColor myDarkishRed = TCODColor::lightRed * 0.5f; @CEx TCOD_color_t my_darkish_red = TCOD_color_multiply_scalar(TCOD_light_red, 0.5f); @PyEx myDarkishRed = litbcod.light_red * 0.5 @C#Ex TCODColor myDarkishRed = TCODColor.lightRed.Multiply(0.5f); @LuaEx myDarkishRed = tcod.color.lightRed * 0.5 */ TCODColor operator *(float value) const { TCOD_color_t ret; int r,g,b; r = (int)(this->r * value); g = (int)(this->g * value); b = (int)(this->b * value); r = CLAMP(0,255,r); g = CLAMP(0,255,g); b = CLAMP(0,255,b); ret.r=(uint8_t)r; ret.g=(uint8_t)g; ret.b=(uint8_t)b; return ret; } /** @PageName color @FuncTitle Adding two colors @FuncDesc c1 = c1 + c2 => c1.r = MIN(255, c1.r + c2.r) c1.g = MIN(255, c1.g + c2.g) c1.b = MIN(255, c1.b + c2.b) lightishRed = red + darkGrey
@CppEx TCODColor myLightishRed = TCODColor::red + TCODColor::darkGrey @CEx TCOD_color_t my_lightish_red = TCOD_color_add(TCOD_red, TCOD_dark_grey); @PyEx myLightishRed = libtcod.red + libtcod.dark_grey @C#Ex TCODColor myLightishRed = TCODColor.red.Plus(TCODColor.darkGrey) @LuaEx myLightishRed = tcod.color.red + tcod.color.darkGrey */ TCODColor operator + (const TCODColor & a) const { TCODColor ret; int r=(int)(this->r)+a.r; int g=(int)(this->g)+a.g; int b=(int)(this->b)+a.b; r = MIN(255,r); g = MIN(255,g); b = MIN(255,b); ret.r=(uint8_t)r; ret.g=(uint8_t)g; ret.b=(uint8_t)b; return ret; } /** @PageName color @FuncTitle Subtract two colors @FuncDesc c1 = c1 - c2 => c1.r = MAX(0, c1.r - c2.r) c1.g = MAX(0, c1.g - c2.g) c1.b = MAX(0, c1.b - c2.b) redish = red - darkGrey
@CppEx TCODColor myRedish = TCODColor::red - TCODColor::darkGrey @CEx TCOD_color_t my_redish = TCOD_color_subtract(TCOD_red, TCOD_dark_grey); @PyEx myRedish = libtcod.red - libtcod.dark_grey @C#Ex TCODColor myRedish = TCODColor.red.Minus(TCODColor.darkGrey) @LuaEx myRedish = tcod.color.red - tcod.color.darkGrey */ TCODColor operator - (const TCODColor & a) const { TCODColor ret; int r=(int)(this->r)-a.r; int g=(int)(this->g)-a.g; int b=(int)(this->b)-a.b; r = MAX(0,r); g = MAX(0,g); b = MAX(0,b); ret.r=(uint8_t)r; ret.g=(uint8_t)g; ret.b=(uint8_t)b; return ret; } /** @PageName color @FuncTitle Interpolate between two colors @FuncDesc c1 = lerp (c2, c3, coef) => c1.r = c2.r + (c3.r - c2.r ) * coef c1.g = c2.g + (c3.g - c2.g ) * coef c1.b = c2.b + (c3.b - c2.b ) * coef coef should be between 0.0 and 1.0 but you can as well use other values
coef == 0.0f
coef == 0.25f
coef == 0.5f
coef == 0.75f
coef == 1.0f
@CppEx TCODColor myColor = TCODColor::lerp ( TCODColor::darkGrey, TCODColor::lightRed,coef ); @CEx TCOD_color_t my_color = TCOD_color_lerp ( TCOD_dark_grey, TCOD_light_red,coef); @PyEx my_color = libtcod.color_lerp ( libtcod.dark_grey, litbcod.light_red,coef) @C#Ex TCODColor myColor = TCODColor.Interpolate( TCODColor.darkGrey, TCODColor.lightRed, coef ); @LuaEx myColor = tcod.color.Interpolate( tcod.color.darkGrey, tcod.color.lightRed, coef ) */ static TCODColor lerp(const TCODColor &a, const TCODColor &b, float coef) { TCODColor ret; ret.r=(uint8_t)(a.r+(b.r-a.r)*coef); ret.g=(uint8_t)(a.g+(b.g-a.g)*coef); ret.b=(uint8_t)(a.b+(b.b-a.b)*coef); return ret; } /** @PageName color @FuncTitle Define a color by its hue, saturation and value @FuncDesc After this function is called, the r,g,b fields of the color are calculated according to the h,s,v parameters. @Cpp void TCODColor::setHSV(float h, float s, float v) @C void TCOD_color_set_HSV(TCOD_color_t *c,float h, float s, float v) @Py color_set_hsv(c,h,s,v) @C# void TCODColor::setHSV(float h, float s, float v) @Lua Color:setHSV( h, s ,v ) @Param c In the C and Python versions, the color to modify @Param h,s,v Color components in the HSV space 0.0 <= h < 360.0 0.0 <= s <= 1.0 0.0 <= v <= 1.0 */ void setHSV(float h, float s, float v); /** @PageName color @FuncTitle Define a color's hue, saturation or lightness @FuncDesc These functions set only a single component in the HSV color space. @Cpp void TCODColor::setHue (float h) void TCODColor::setSaturation (float s) void TCODColor::setValue (float v) @C void TCOD_color_set_hue (TCOD_color_t *c, float h) void TCOD_color_set_saturation (TCOD_color_t *c, float s) void TCOD_color_set_value (TCOD_color_t *c, float v) @Lua Color:setHue(h) Color:setSaturation(s) Color:setValue(v) @Param h,s,v Color components in the HSV space @Param c In the C and Python versions, the color to modify */ void setHue (float h); void setSaturation (float s); void setValue (float v); /** @PageName color @FuncTitle Get a color hue, saturation and value components @Cpp void TCODColor::getHSV(float *h, float *s, float *v) const @C void TCOD_color_get_HSV(TCOD_color_t c,float * h, float * s, float * v) @Py color_get_HSV(c) # returns [h,s,v] @C# void TCODColor::getHSV(out float h, out float s, out float v) @Lua Color:getHSV() -- returns h,s,v @Param c In the C and Python versions, the TCOD_color_t from which to read. @Param h,s,v Color components in the HSV space 0.0 <= h < 360.0 0.0 <= s <= 1.0 0.0 <= v <= 1.0 */ void getHSV(float *h, float *s, float *v) const; /** @PageName color @FuncTitle Get a color's hue, saturation or value @FuncDesc Should you need to extract only one of the HSV components, these functions are what you should call. Note that if you need all three values, it's way less burdensome for the CPU to call TCODColor::getHSV(). @Cpp float TCODColor::getHue () float TCODColor::getSaturation () float TCODColor::getValue () @C float TCOD_color_get_hue (TCOD_color_t c) float TCOD_color_get_saturation (TCOD_color_t c) float TCOD_color_get_value (TCOD_color_t c) @Lua Color:getHue() Color:getSaturation() Color:getValue() @C# float TCODColor::getHue() float TCODColor::getSaturation() float TCODColor::getValue() @Param c the TCOD_color_t from which to read */ float getHue (); float getSaturation (); float getValue (); /** @PageName color @FuncTitle Shift a color's hue up or down @FuncDesc The hue shift value is the number of grades the color's hue will be shifted. The value can be negative for shift left, or positive for shift right. Resulting values H < 0 and H >= 360 are handled automatically. @Cpp void TCODColor::shiftHue (float hshift) @C void TCOD_color_shift_hue (TCOD_color_t *c, float hshift) @C# TCODColor::shiftHue(float hshift) @Lua Color:shiftHue(hshift) @Param c The color to modify @Param hshift The hue shift value */ void shiftHue (float hshift); /** @PageName color @FuncTitle Scale a color's saturation and value @Cpp void TCODColor::scaleHSV (float sscale, float vscale) @C void TCOD_color_scale_HSV (TCOD_color_t *c, float scoef, float vcoef) @Py color_scale_HSV(c, scoef, vcoef) @C# TCODColor::scaleHSV (float sscale, float vscale) @Lua Color:scaleHSV(sscale,vscale) @Param c The color to modify @Param sscale saturation multiplier (1.0f for no change) @Param vscale value multiplier (1.0f for no change) */ void scaleHSV (float sscale, float vscale); /** @PageName color @FuncTitle Generate a smooth color map @FuncDesc You can define a color map from an array of color keys. Colors will be interpolated between the keys. 0 -> black 4 -> red 8 -> white Result :
map[0]
 black
map[1]
 
map[2]
 
map[3]
 
map[4]
 red
map[5]
 
map[6]
 
map[7]
 
map[8]
 white
@Cpp static void genMap(TCODColor *map, int nbKey, TCODColor const *keyColor, int const *keyIndex) @C void TCOD_gen_map(TCOD_color_t *map, int nb_key, TCOD_color_t const *key_color, int const *key_index) @Py color_gen_map(keyColor,keyIndex) # returns an array of colors @Param map An array of colors to be filled by the function. @Param nbKey Number of color keys @Param keyColor Array of nbKey colors containing the color of each key @Param keyIndex Array of nbKey integers containing the index of each key. If you want to fill the map array, keyIndex[0] must be 0 and keyIndex[nbKey-1] is the number of elements in map minus 1 but you can also use the function to fill only a part of the map array. @CppEx int idx[] = { 0, 4, 8 }; // indexes of the keys TCODColor col[] = { TCODColor( 0,0,0 ), TCODColor(255,0,0), TCODColor(255,255,255) }; // colors : black, red, white TCODColor map[9]; TCODColor::genMap(map,3,col,idx); @CEx int idx[] = { 0, 4, 8 }; // indexes of the keys TCOD_color_t col[] = { { 0,0,0 }, {255,0,0}, {255,255,255} }; // colors : black, red, white TCOD_color_t map[9]; TCOD_color_gen_map(map,3,col,idx); @PyEx idx = [ 0, 4, 8 ] # indexes of the keys col = [ libtcod.Color( 0,0,0 ), libtcod.Color( 255,0,0 ), libtcod.Color(255,255,255) ] # colors : black, red, white map=libtcod.color_gen_map(col,idx) */ static void genMap(TCODColor *map, int nbKey, TCODColor const *keyColor, int const *keyIndex); // color array static const TCODColor colors[TCOD_COLOR_NB][TCOD_COLOR_LEVELS]; // grey levels static const TCODColor black; static const TCODColor darkestGrey; static const TCODColor darkerGrey; static const TCODColor darkGrey; static const TCODColor grey; static const TCODColor lightGrey; static const TCODColor lighterGrey; static const TCODColor lightestGrey; static const TCODColor white; //sepia static const TCODColor darkestSepia; static const TCODColor darkerSepia; static const TCODColor darkSepia; static const TCODColor sepia; static const TCODColor lightSepia; static const TCODColor lighterSepia; static const TCODColor lightestSepia; // standard colors static const TCODColor red; static const TCODColor flame; static const TCODColor orange; static const TCODColor amber; static const TCODColor yellow; static const TCODColor lime; static const TCODColor chartreuse; static const TCODColor green; static const TCODColor sea; static const TCODColor turquoise; static const TCODColor cyan; static const TCODColor sky; static const TCODColor azure; static const TCODColor blue; static const TCODColor han; static const TCODColor violet; static const TCODColor purple; static const TCODColor fuchsia; static const TCODColor magenta; static const TCODColor pink; static const TCODColor crimson; // dark colors static const TCODColor darkRed; static const TCODColor darkFlame; static const TCODColor darkOrange; static const TCODColor darkAmber; static const TCODColor darkYellow; static const TCODColor darkLime; static const TCODColor darkChartreuse; static const TCODColor darkGreen; static const TCODColor darkSea; static const TCODColor darkTurquoise; static const TCODColor darkCyan; static const TCODColor darkSky; static const TCODColor darkAzure; static const TCODColor darkBlue; static const TCODColor darkHan; static const TCODColor darkViolet; static const TCODColor darkPurple; static const TCODColor darkFuchsia; static const TCODColor darkMagenta; static const TCODColor darkPink; static const TCODColor darkCrimson; // darker colors static const TCODColor darkerRed; static const TCODColor darkerFlame; static const TCODColor darkerOrange; static const TCODColor darkerAmber; static const TCODColor darkerYellow; static const TCODColor darkerLime; static const TCODColor darkerChartreuse; static const TCODColor darkerGreen; static const TCODColor darkerSea; static const TCODColor darkerTurquoise; static const TCODColor darkerCyan; static const TCODColor darkerSky; static const TCODColor darkerAzure; static const TCODColor darkerBlue; static const TCODColor darkerHan; static const TCODColor darkerViolet; static const TCODColor darkerPurple; static const TCODColor darkerFuchsia; static const TCODColor darkerMagenta; static const TCODColor darkerPink; static const TCODColor darkerCrimson; // darkest colors static const TCODColor darkestRed; static const TCODColor darkestFlame; static const TCODColor darkestOrange; static const TCODColor darkestAmber; static const TCODColor darkestYellow; static const TCODColor darkestLime; static const TCODColor darkestChartreuse; static const TCODColor darkestGreen; static const TCODColor darkestSea; static const TCODColor darkestTurquoise; static const TCODColor darkestCyan; static const TCODColor darkestSky; static const TCODColor darkestAzure; static const TCODColor darkestBlue; static const TCODColor darkestHan; static const TCODColor darkestViolet; static const TCODColor darkestPurple; static const TCODColor darkestFuchsia; static const TCODColor darkestMagenta; static const TCODColor darkestPink; static const TCODColor darkestCrimson; // light colors static const TCODColor lightRed; static const TCODColor lightFlame; static const TCODColor lightOrange; static const TCODColor lightAmber; static const TCODColor lightYellow; static const TCODColor lightLime; static const TCODColor lightChartreuse; static const TCODColor lightGreen; static const TCODColor lightSea; static const TCODColor lightTurquoise; static const TCODColor lightCyan; static const TCODColor lightSky; static const TCODColor lightAzure; static const TCODColor lightBlue; static const TCODColor lightHan; static const TCODColor lightViolet; static const TCODColor lightPurple; static const TCODColor lightFuchsia; static const TCODColor lightMagenta; static const TCODColor lightPink; static const TCODColor lightCrimson; //lighter colors static const TCODColor lighterRed; static const TCODColor lighterFlame; static const TCODColor lighterOrange; static const TCODColor lighterAmber; static const TCODColor lighterYellow; static const TCODColor lighterLime; static const TCODColor lighterChartreuse; static const TCODColor lighterGreen; static const TCODColor lighterSea; static const TCODColor lighterTurquoise; static const TCODColor lighterCyan; static const TCODColor lighterSky; static const TCODColor lighterAzure; static const TCODColor lighterBlue; static const TCODColor lighterHan; static const TCODColor lighterViolet; static const TCODColor lighterPurple; static const TCODColor lighterFuchsia; static const TCODColor lighterMagenta; static const TCODColor lighterPink; static const TCODColor lighterCrimson; // lightest colors static const TCODColor lightestRed; static const TCODColor lightestFlame; static const TCODColor lightestOrange; static const TCODColor lightestAmber; static const TCODColor lightestYellow; static const TCODColor lightestLime; static const TCODColor lightestChartreuse; static const TCODColor lightestGreen; static const TCODColor lightestSea; static const TCODColor lightestTurquoise; static const TCODColor lightestCyan; static const TCODColor lightestSky; static const TCODColor lightestAzure; static const TCODColor lightestBlue; static const TCODColor lightestHan; static const TCODColor lightestViolet; static const TCODColor lightestPurple; static const TCODColor lightestFuchsia; static const TCODColor lightestMagenta; static const TCODColor lightestPink; static const TCODColor lightestCrimson; // desaturated colors static const TCODColor desaturatedRed; static const TCODColor desaturatedFlame; static const TCODColor desaturatedOrange; static const TCODColor desaturatedAmber; static const TCODColor desaturatedYellow; static const TCODColor desaturatedLime; static const TCODColor desaturatedChartreuse; static const TCODColor desaturatedGreen; static const TCODColor desaturatedSea; static const TCODColor desaturatedTurquoise; static const TCODColor desaturatedCyan; static const TCODColor desaturatedSky; static const TCODColor desaturatedAzure; static const TCODColor desaturatedBlue; static const TCODColor desaturatedHan; static const TCODColor desaturatedViolet; static const TCODColor desaturatedPurple; static const TCODColor desaturatedFuchsia; static const TCODColor desaturatedMagenta; static const TCODColor desaturatedPink; static const TCODColor desaturatedCrimson; // metallic static const TCODColor brass; static const TCODColor copper; static const TCODColor gold; static const TCODColor silver; // miscellaneous static const TCODColor celadon; static const TCODColor peach; }; TCODLIB_API TCODColor operator *(float value, const TCODColor &c); #endif libtcod-1.6.4+dfsg/include/console.h000066400000000000000000000210661321276576200173370ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_CONSOLE_H #define _TCOD_CONSOLE_H #include "libtcod_portability.h" #ifdef TCOD_CONSOLE_SUPPORT #include "color.h" #include "console_types.h" #include "image.h" #include "list.h" #ifdef __cplusplus extern "C" { #endif #define TCOD_BKGND_ALPHA(alpha) ((TCOD_bkgnd_flag_t)(TCOD_BKGND_ALPH|(((uint8_t)(alpha*255))<<8))) #define TCOD_BKGND_ADDALPHA(alpha) ((TCOD_bkgnd_flag_t)(TCOD_BKGND_ADDA|(((uint8_t)(alpha*255))<<8))) TCODLIB_API void TCOD_console_init_root(int w, int h, const char * title, bool fullscreen, TCOD_renderer_t renderer); TCODLIB_API void TCOD_console_set_window_title(const char *title); TCODLIB_API void TCOD_console_set_fullscreen(bool fullscreen); TCODLIB_API bool TCOD_console_is_fullscreen(void); TCODLIB_API bool TCOD_console_is_window_closed(void); TCODLIB_API bool TCOD_console_has_mouse_focus(void); TCODLIB_API bool TCOD_console_is_active(void); TCODLIB_API void TCOD_console_set_custom_font(const char *fontFile, int flags,int nb_char_horiz, int nb_char_vertic); TCODLIB_API void TCOD_console_map_ascii_code_to_font(int asciiCode, int fontCharX, int fontCharY); TCODLIB_API void TCOD_console_map_ascii_codes_to_font(int asciiCode, int nbCodes, int fontCharX, int fontCharY); TCODLIB_API void TCOD_console_map_string_to_font(const char *s, int fontCharX, int fontCharY); TCODLIB_API void TCOD_console_set_dirty(int x, int y, int w, int h); TCODLIB_API void TCOD_console_set_default_background(TCOD_console_t con,TCOD_color_t col); TCODLIB_API void TCOD_console_set_default_foreground(TCOD_console_t con,TCOD_color_t col); TCODLIB_API void TCOD_console_clear(TCOD_console_t con); TCODLIB_API void TCOD_console_set_char_background(TCOD_console_t con,int x, int y, TCOD_color_t col, TCOD_bkgnd_flag_t flag); TCODLIB_API void TCOD_console_set_char_foreground(TCOD_console_t con,int x, int y, TCOD_color_t col); TCODLIB_API void TCOD_console_set_char(TCOD_console_t con,int x, int y, int c); TCODLIB_API void TCOD_console_put_char(TCOD_console_t con,int x, int y, int c, TCOD_bkgnd_flag_t flag); TCODLIB_API void TCOD_console_put_char_ex(TCOD_console_t con,int x, int y, int c, TCOD_color_t fore, TCOD_color_t back); TCODLIB_API void TCOD_console_set_background_flag(TCOD_console_t con,TCOD_bkgnd_flag_t flag); TCODLIB_API TCOD_bkgnd_flag_t TCOD_console_get_background_flag(TCOD_console_t con); TCODLIB_API void TCOD_console_set_alignment(TCOD_console_t con,TCOD_alignment_t alignment); TCODLIB_API TCOD_alignment_t TCOD_console_get_alignment(TCOD_console_t con); TCODLIB_API void TCOD_console_print(TCOD_console_t con,int x, int y, const char *fmt, ...); TCODLIB_API void TCOD_console_print_ex(TCOD_console_t con,int x, int y, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment, const char *fmt, ...); TCODLIB_API int TCOD_console_print_rect(TCOD_console_t con,int x, int y, int w, int h, const char *fmt, ...); TCODLIB_API int TCOD_console_print_rect_ex(TCOD_console_t con,int x, int y, int w, int h, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment, const char *fmt, ...); TCODLIB_API int TCOD_console_get_height_rect(TCOD_console_t con,int x, int y, int w, int h, const char *fmt, ...); TCODLIB_API void TCOD_console_rect(TCOD_console_t con,int x, int y, int w, int h, bool clear, TCOD_bkgnd_flag_t flag); TCODLIB_API void TCOD_console_hline(TCOD_console_t con,int x,int y, int l, TCOD_bkgnd_flag_t flag); TCODLIB_API void TCOD_console_vline(TCOD_console_t con,int x,int y, int l, TCOD_bkgnd_flag_t flag); TCODLIB_API void TCOD_console_print_frame(TCOD_console_t con,int x,int y,int w,int h, bool empty, TCOD_bkgnd_flag_t flag, const char *fmt, ...); #ifndef NO_UNICODE /* unicode support */ TCODLIB_API void TCOD_console_map_string_to_font_utf(const wchar_t *s, int fontCharX, int fontCharY); TCODLIB_API void TCOD_console_print_utf(TCOD_console_t con,int x, int y, const wchar_t *fmt, ...); TCODLIB_API void TCOD_console_print_ex_utf(TCOD_console_t con,int x, int y, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment, const wchar_t *fmt, ...); TCODLIB_API int TCOD_console_print_rect_utf(TCOD_console_t con,int x, int y, int w, int h, const wchar_t *fmt, ...); TCODLIB_API int TCOD_console_print_rect_ex_utf(TCOD_console_t con,int x, int y, int w, int h, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment, const wchar_t *fmt, ...); TCODLIB_API int TCOD_console_get_height_rect_utf(TCOD_console_t con,int x, int y, int w, int h, const wchar_t *fmt, ...); #endif TCODLIB_API TCOD_color_t TCOD_console_get_default_background(TCOD_console_t con); TCODLIB_API TCOD_color_t TCOD_console_get_default_foreground(TCOD_console_t con); TCODLIB_API TCOD_color_t TCOD_console_get_char_background(TCOD_console_t con,int x, int y); TCODLIB_API TCOD_color_t TCOD_console_get_char_foreground(TCOD_console_t con,int x, int y); TCODLIB_API int TCOD_console_get_char(TCOD_console_t con,int x, int y); TCODLIB_API TCOD_image_t TCOD_console_get_background_color_image(TCOD_console_t con); TCODLIB_API TCOD_image_t TCOD_console_get_foreground_color_image(TCOD_console_t con); TCODLIB_API void TCOD_console_set_fade(uint8_t val, TCOD_color_t fade); TCODLIB_API uint8_t TCOD_console_get_fade(void); TCODLIB_API TCOD_color_t TCOD_console_get_fading_color(void); TCODLIB_API void TCOD_console_flush(void); TCODLIB_API void TCOD_console_set_color_control(TCOD_colctrl_t con, TCOD_color_t fore, TCOD_color_t back); TCODLIB_API TCOD_key_t TCOD_console_check_for_keypress(int flags); TCODLIB_API TCOD_key_t TCOD_console_wait_for_keypress(bool flush); TCODLIB_API bool TCOD_console_is_key_pressed(TCOD_keycode_t key); /* ASCII paint file support */ TCODLIB_API TCOD_console_t TCOD_console_from_file(const char *filename); TCODLIB_API bool TCOD_console_load_asc(TCOD_console_t con, const char *filename); TCODLIB_API bool TCOD_console_load_apf(TCOD_console_t con, const char *filename); TCODLIB_API bool TCOD_console_save_asc(TCOD_console_t con, const char *filename); TCODLIB_API bool TCOD_console_save_apf(TCOD_console_t con, const char *filename); TCODLIB_API TCOD_console_t TCOD_console_new(int w, int h); TCODLIB_API int TCOD_console_get_width(TCOD_console_t con); TCODLIB_API int TCOD_console_get_height(TCOD_console_t con); TCODLIB_API void TCOD_console_set_key_color(TCOD_console_t con,TCOD_color_t col); TCODLIB_API void TCOD_console_blit(TCOD_console_t src,int xSrc, int ySrc, int wSrc, int hSrc, TCOD_console_t dst, int xDst, int yDst, float foreground_alpha, float background_alpha); TCODLIB_API void TCOD_console_delete(TCOD_console_t console); TCODLIB_API void TCOD_console_credits(void); TCODLIB_API void TCOD_console_credits_reset(void); TCODLIB_API bool TCOD_console_credits_render(int x, int y, bool alpha); /* REXPaint support */ TCODLIB_API TCOD_console_t TCOD_console_from_xp(const char *filename); TCODLIB_API bool TCOD_console_load_xp(TCOD_console_t con, const char *filename); TCODLIB_API bool TCOD_console_save_xp(TCOD_console_t con, const char *filename, int compress_level); TCODLIB_API TCOD_list_t TCOD_console_list_from_xp(const char *filename); TCODLIB_API bool TCOD_console_list_save_xp(TCOD_list_t console_list, const char *filename, int compress_level); #ifdef __cplusplus } #endif #endif /* TCOD_CONSOLE_SUPPORT */ #endif /* _TCOD_CONSOLE_H */ libtcod-1.6.4+dfsg/include/console.hpp000066400000000000000000002507721321276576200177070ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_CONSOLE_HPP #define _TCOD_CONSOLE_HPP #include "console.h" #ifdef TCOD_CONSOLE_SUPPORT #include "image.hpp" #include "color.hpp" class TCODImage; /** @PageName console @PageCategory Core @PageTitle Console @PageDesc The console emulator handles the rendering of the game screen and the keyboard input. Classic real time game loop: @Cpp TCODConsole::initRoot(80,50,"my game",false); TCODSystem::setFps(25); // limit framerate to 25 frames per second while (!endGame && !TCODConsole::isWindowClosed()) { TCOD_key_t key; TCODSystem::checkForEvent(TCOD_EVENT_KEY_PRESS,&key,NULL); updateWorld (key, TCODSystem::getLastFrameLength()); // updateWorld(TCOD_key_t key, float elapsed) (using key if key.vk != TCODK_NONE) // use elapsed to scale any update that is time dependent. // ... draw world+GUI on TCODConsole::root TCODConsole::flush(); } @Lua tcod.console.initRoot(80,50,"my game", false) root=libtcod.TCODConsole_root tcod.system.setFps(25) while not tcod.console.isWindowClosed() do -- ... draw on root tcod.console.flush() key=tcod.console.checkForKeypress() -- ... update world, using key and tcod.system.getLastFrameLength end */ /** @PageName console @FuncDesc Classic turn by turn game loop: @Cpp TCODConsole::initRoot(80,50,"my game",false); while (!endGame && !TCODConsole::isWindowClosed()) { // ... draw on TCODConsole::root TCODConsole::flush(); TCOD_key_t key; TCODConsole::waitForEvent(TCOD_EVENT_KEY_PRESS,&key,NULL,true); //... update world, using key } */ class TCODLIB_API TCODConsole { public : /** @PageName console_init @PageTitle Initializing the console @PageFather console */ static TCODConsole *root; /** @PageName console_init_root @PageTitle Creating the game window @PageFather console_init @Cpp static void TCODConsole::initRoot (int w, int h, const char * title, bool fullscreen = false, TCOD_renderer_t renderer = TCOD_RENDERER_SDL) @C void TCOD_console_init_root (int w, int h, const char * title, bool fullscreen, TCOD_renderer_t renderer) @Py console_init_root (w, h, title, fullscreen = False, renderer = RENDERER_SDL) @C# static void TCODConsole::initRoot(int w, int h, string title) static void TCODConsole::initRoot(int w, int h, string title, bool fullscreen) static void TCODConsole::initRoot(int w, int h, string title, bool fullscreen, TCODRendererType renderer) @Lua tcod.console.initRoot(w,h,title) -- fullscreen = false, renderer = SDL tcod.console.initRoot(w,h,title,fullscreen) -- renderer = SDL tcod.console.initRoot(w,h,title,fullscreen,renderer) -- renderers : tcod.GLSL, tcod.OpenGL, tcod.SDL @Param w,h size of the console(in characters). The default font in libtcod (./terminal.png) uses 8x8 pixels characters. You can change the font by calling TCODConsole::setCustomFont before calling initRoot. @Param title title of the window. It's not visible when you are in fullscreen. Note 1 : you can dynamically change the window title with TCODConsole::setWindowTitle @Param fullscreen whether you start in windowed or fullscreen mode. Note 1 : you can dynamically change this mode with TCODConsole::setFullscreen Note 2 : you can get current mode with TCODConsole::isFullscreen @Param renderer which renderer to use. Possible values are : * TCOD_RENDERER_GLSL : works only on video cards with pixel shaders * TCOD_RENDERER_OPENGL : works on all video cards supporting OpenGL 1.4 * TCOD_RENDERER_SDL : should work everywhere! Note 1: if you select a renderer that is not supported by the player's machine, libtcod scan the lower renderers until it finds a working one. Note 2: on recent video cards, GLSL results in up to 900% increase of framerates in the true color sample compared to SDL renderer. Note 3: whatever renderer you use, it can always be overridden by the player through the libtcod.cfg file. Note 4: you can dynamically change the renderer after calling initRoot with TCODSystem::setRenderer. Note 5: you can get current renderer with TCODSystem::getRenderer. It might be different from the one you set in initRoot in case it's not supported on the player's computer. @CppEx TCODConsole::initRoot(80, 50, "The Chronicles Of Doryen v0.1"); @CEx TCOD_console_init_root(80, 50, "The Chronicles Of Doryen v0.1", false, TCOD_RENDERER_OPENGL); @PyEx libtcod.console_init_root(80, 50, 'The Chronicles Of Doryen v0.1') @LuaEx tcod.console.initRoot(80,50,"The Chronicles Of Doryen v0.1") */ static void initRoot(int w, int h, const char * title, bool fullscreen = false, TCOD_renderer_t renderer=TCOD_RENDERER_SDL); /** @PageName console_set_custom_font @PageTitle Using a custom bitmap font @PageFather console_init @FuncTitle setCustomFont @FuncDesc This function allows you to use a bitmap font (png or bmp) with custom character size or layout. It should be called before initializing the root console with initRoot. Once this function is called, you can define your own custom mappings using mapping functions
Different font layouts
ASCII_INROWASCII_INCOLTCOD
  • ascii, in columns : characters 0 to 15 are in the first column. The space character is at coordinates 2,0.
  • ascii, in rows : characters 0 to 15 are in the first row. The space character is at coordinates 0,2.
  • tcod : special mapping. Not all ascii values are mapped. The space character is at coordinates 0,0.
Different font types
standard
(non antialiased)
antialiased
(32 bits PNG)
antialiased
(greyscale)
  • standard : transparency is given by a key color automatically detected by looking at the color of the space character
  • 32 bits : transparency is given by the png alpha layer. The font color does not matter but it must be desaturated
  • greyscale : transparency is given by the pixel value. You can use white characters on black background or black characters on white background. The background color is automatically detected by looking at the color of the space character
Examples of fonts can be found in libtcod's fonts directory. Check the Readme file there. @Cpp static void TCODConsole::setCustomFont(const char *fontFile, int flags=TCOD_FONT_LAYOUT_ASCII_INCOL,int nbCharHoriz=0, int nbCharVertic=0) @C void TCOD_console_set_custom_font(const char *fontFile, int flags,int nb_char_horiz, int nb_char_vertic) @Py console_set_custom_font(fontFile, flags=FONT_LAYOUT_ASCII_INCOL,nb_char_horiz=0, nb_char_vertic=0) @C# static void TCODConsole::setCustomFont(string fontFile) static void TCODConsole::setCustomFont(string fontFile, int flags) static void TCODConsole::setCustomFont(string fontFile, int flags, int nbCharHoriz) static void TCODConsole::setCustomFont(string fontFile, int flags, int nbCharHoriz, int nbCharVertic) @Lua tcod.console.setCustomFont(fontFile) tcod.console.setCustomFont(fontFile, flags) tcod.console.setCustomFont(fontFile, nbCharHoriz) tcod.console.setCustomFont(fontFile, flags, nbCharHoriz, nbCharVertic) -- flags : tcod.LayoutAsciiInColumn, tcod.LayoutAsciiInRow, tcod.LayoutTCOD, tcod.Greyscale @Param fontFile Name of a .bmp or .png file containing the font. @Param flags Used to define the characters layout in the bitmap and the font type : TCOD_FONT_LAYOUT_ASCII_INCOL : characters in ASCII order, code 0-15 in the first column TCOD_FONT_LAYOUT_ASCII_INROW : characters in ASCII order, code 0-15 in the first row TCOD_FONT_LAYOUT_TCOD : simplified layout. See examples below. TCOD_FONT_TYPE_GREYSCALE : create an anti-aliased font from a greyscale bitmap For Python, remove TCOD _ : libtcod.FONT_LAYOUT_ASCII_INCOL @Param nbCharHoriz,nbCharVertic Number of characters in the font. Should be 16x16 for ASCII layouts, 32x8 for TCOD layout. But you can use any other layout. If set to 0, there are deduced from the font layout flag. @CppEx TCODConsole::setCustomFont("standard_8x8_ascii_in_col_font.bmp",TCOD_FONT_LAYOUT_ASCII_INCOL); TCODConsole::setCustomFont("32bits_8x8_ascii_in_row_font.png",TCOD_FONT_LAYOUT_ASCII_INROW); TCODConsole::setCustomFont("greyscale_8x8_tcod_font.png",TCOD_FONT_LAYOUT_TCOD | TCOD_FONT_TYPE_GREYSCALE); @CEx TCOD_console_set_custom_font("standard_8x8_ascii_in_col_font.bmp",TCOD_FONT_LAYOUT_ASCII_INCOL,16,16); TCOD_console_set_custom_font("32bits_8x8_ascii_in_row_font.png",TCOD_FONT_LAYOUT_ASCII_INROW,32,8); TCOD_console_set_custom_font("greyscale_8x8_tcod_font.png",TCOD_FONT_LAYOUT_TCOD | TCOD_FONT_TYPE_GREYSCALE,32,8); @PyEx libtcod.console_set_custom_font("standard_8x8_ascii_in_col_font.bmp",libtcod.FONT_LAYOUT_ASCII_INCOL) libtcod.console_set_custom_font("32bits_8x8_ascii_in_row_font.png",libtcod.FONT_LAYOUT_ASCII_INROW) libtcod.console_set_custom_font("greyscale_8x8_tcod_font.png",libtcod.FONT_LAYOUT_TCOD | libtcod.FONT_TYPE_GREYSCALE) @LuaEx tcod.console.setCustomFont("standard_8x8_ascii_in_col_font.bmp",tcod.LayoutAsciiInColumn); tcod.console.setCustomFont("32bits_8x8_ascii_in_row_font.png",tcod.LayoutAsciiInRow); tcod.console.setCustomFont("greyscale_8x8_tcod_font.png",tcod.LayoutTCOD + tcod.Greyscale); */ static void setCustomFont(const char *fontFile, int flags=TCOD_FONT_LAYOUT_ASCII_INCOL,int nbCharHoriz=0, int nbCharVertic=0); /** @PageName console_map @PageTitle Using custom characters mapping @PageFather console_init @FuncTitle Mapping a single ASCII code to a character @PageDesc These functions allow you to map characters in the bitmap font to ASCII codes. They should be called after initializing the root console with initRoot. You can dynamically change the characters mapping at any time, allowing to use several fonts in the same screen. @Cpp static void TCODConsole::mapAsciiCodeToFont(int asciiCode, int fontCharX, int fontCharY) @C void TCOD_console_map_ascii_code_to_font(int asciiCode, int fontCharX, int fontCharY) @Py console_map_ascii_code_to_font(asciiCode, fontCharX, fontCharY) @C# static void TCODConsole::mapAsciiCodeToFont(int asciiCode, int fontCharX, int fontCharY) @Lua tcod.console.mapAsciiCodeToFont(asciiCode, fontCharX, fontCharY) @Param asciiCode ASCII code to map. @Param fontCharX,fontCharY Coordinate of the character in the bitmap font (in characters, not pixels). */ static void mapAsciiCodeToFont(int asciiCode, int fontCharX, int fontCharY); /** @PageName console_map @FuncTitle Mapping consecutive ASCII codes to consecutive characters @Cpp static void TCODConsole::mapAsciiCodesToFont(int firstAsciiCode, int nbCodes, int fontCharX, int fontCharY) @C void TCOD_console_map_ascii_codes_to_font(int firstAsciiCode, int nbCodes, int fontCharX, int fontCharY) @Py console_map_ascii_codes_to_font(firstAsciiCode, nbCodes, fontCharX, fontCharY) @C# static void TCODConsole::mapAsciiCodesToFont(int firstAsciiCode, int nbCodes, int fontCharX, int fontCharY) @Lua tcod.console.mapAsciiCodesToFont(firstAsciiCode, nbCodes, fontCharX, fontCharY) @Param firstAsciiCode first ASCII code to map @Param nbCodes number of consecutive ASCII codes to map @Param fontCharX,fontCharY coordinate of the character in the bitmap font (in characters, not pixels) corresponding to the first ASCII code */ static void mapAsciiCodesToFont(int firstAsciiCode, int nbCodes, int fontCharX, int fontCharY); /** @PageName console_map @FuncTitle Mapping ASCII code from a string to consecutive characters @Cpp static void TCODConsole::mapStringToFont(const char *s, int fontCharX, int fontCharY) @C void TCOD_console_map_string_to_font(const char *s, int fontCharX, int fontCharY) @Py console_map_string_to_font(s, fontCharX, fontCharY) @C# static void TCODConsole::mapStringToFont(string s, int fontCharX, int fontCharY) @Lua tcod.console.mapStringToFont(s, fontCharX, fontCharY) @Param s string containing the ASCII codes to map @Param fontCharX,fontCharY coordinate of the character in the bitmap font (in characters, not pixels) corresponding to the first ASCII code in the string */ static void mapStringToFont(const char *s, int fontCharX, int fontCharY); /** @PageName console_fullscreen @PageTitle Fullscreen mode @PageFather console_init @FuncTitle Getting the current mode @FuncDesc This function returns true if the current mode is fullscreen. @Cpp static bool TCODConsole::isFullscreen() @C bool TCOD_console_is_fullscreen() @Py console_is_fullscreen() @C# static bool TCODConsole::isFullscreen() @Lua tcod.console.isFullscreen() */ static bool isFullscreen(); /** @PageName console_fullscreen @FuncTitle Switching between windowed and fullscreen modes @FuncDesc This function switches the root console to fullscreen or windowed mode. Note that there is no predefined key combination to switch to/from fullscreen. You have to do this in your own code. @Cpp static void TCODConsole::setFullscreen(bool fullscreen) @C void TCOD_console_set_fullscreen(bool fullscreen) @Py console_set_fullscreen(fullscreen) @C# static void TCODConsole::setFullscreen(bool fullscreen) @Lua tcod.console.setFullscreen(fullscreen) @Param fullscreen true to switch to fullscreen mode. false to switch to windowed mode. @CppEx TCOD_key_t key; TCODConsole::checkForEvent(TCOD_EVENT_KEY_PRESS,&key,NULL); if ( key.vk == TCODK_ENTER && key.lalt ) TCODConsole::setFullscreen(!TCODConsole::isFullscreen()); @CEx TCOD_key_t key; TCOD_console_check_for_event(TCOD_EVENT_KEY_PRESS,&key,NULL); if ( key.vk == TCODK_ENTER && key.lalt ) TCOD_console_set_fullscreen(!TCOD_console_is_fullscreen()); @PyEx key=Key() libtcod.console_check_for_event(libtcod.EVENT_KEY_PRESS,key,0) if key.vk == libtcod.KEY_ENTER and key.lalt : libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) @LuaEx key=tcod.console.checkForKeypress() if key.KeyCode == tcod.Enter and key.LeftAlt then tcod.console.setFullscreen(not tcod.console.isFullscreen()) end */ static void setFullscreen(bool fullscreen); /** @PageName console_window @PageFather console_init @PageTitle Communicate with the window manager @FuncTitle Changing the window title @FuncDesc This function dynamically changes the title of the game window. Note that the window title is not visible while in fullscreen. @Cpp static void TCODConsole::setWindowTitle(const char *title) @C void TCOD_console_set_window_title(const char *title) @Py console_set_window_title(title) @C# static void TCODConsole::setWindowTitle(string title) @Lua tcod.console.setWindowTitle(title) @Param title New title of the game window */ static void setWindowTitle(const char *title); /** @PageName console_window @FuncTitle Handling "close window" events @FuncDesc When you start the program, this returns false. Once a "close window" event has been sent by the window manager, it will always return true. You're supposed to exit cleanly the game. @Cpp static bool TCODConsole::isWindowClosed() @C bool TCOD_console_is_window_closed() @Py console_is_window_closed() @C# static bool TCODConsole::isWindowClosed() @Lua tcod.console.isWindowClosed() */ static bool isWindowClosed(); /** @PageName console_window @FuncTitle Check if the mouse cursor is inside the game window @FuncDesc Returns true if the mouse cursor is inside the game window area and the game window is the active application. @Cpp static bool TCODConsole::hasMouseFocus() @C bool TCOD_console_has_mouse_focus() @Py console_has_mouse_focus() */ static bool hasMouseFocus(); /** @PageName console_window @FuncTitle Check if the game application is active @FuncDesc Returns false if the game window is not the active window or is iconified. @Cpp static bool TCODConsole::isActive() @C bool TCOD_console_is_active() @Py console_is_active() */ static bool isActive(); /** @PageName console_credits @PageTitle libtcod's credits @PageFather console_init @PageDesc Use these functions to display credits, as seen in the samples. @FuncTitle Using a separate credit page @FuncDesc You can print a "Powered by libtcod x.y.z" screen during your game startup simply by calling this function after initRoot. The credits screen can be skipped by pressing any key. @Cpp static void TCODConsole::credits() @C void TCOD_console_credits() @Py console_credits() @C# static void TCODConsole::credits() @Lua tcod.console.credits() */ static void credits(); /** @PageName console_credits @FuncTitle Embedding credits in an existing page @FuncDesc You can also print the credits on one of your game screens (your main menu for example) by calling this function in your main loop. This function returns true when the credits screen is finished, indicating that you no longer need to call it. @Cpp static bool TCODConsole::renderCredits(int x, int y, bool alpha) @C bool TCOD_console_credits_render(int x, int y, bool alpha) @Py bool TCOD_console_credits_render(int x, int y, bool alpha) @C# static bool TCODConsole::renderCredits(int x, int y, bool alpha) @Lua tcod.console.renderCredits(x, y, alpha) @Param x,y Position of the credits text in your root console @Param alpha If true, credits are transparently added on top of the existing screen. For this to work, this function must be placed between your screen rendering code and the console flush. @CppEx TCODConsole::initRoot(80,50,"The Chronicles Of Doryen v0.1",false); // initialize the root console bool endCredits=false; while ( ! TCODConsole::isWindowClosed() ) { // your game loop // your game rendering here... // render transparent credits near the center of the screen if (! endCredits ) endCredits=TCODConsole::renderCredits(35,25,true); TCODConsole::flush(); } @CEx TCOD_console_init_root(80,50,"The Chronicles Of Doryen v0.1",false); bool end_credits=false; while ( ! TCOD_console_is_window_closed() ) { // your game rendering here... // render transparent credits near the center of the screen if (! end_credits ) end_credits=TCOD_console_credits_render(35,25,true); TCOD_console_flush(); } @PyEx libtcod.console_init_root(80,50,"The Chronicles Of Doryen v0.1",False) end_credits=False while not libtcod.console_is_window_closed() : // your game rendering here... // render transparent credits near the center of the screen if (not end_credits ) : end_credits=libtcod.console_credits_render(35,25,True) libtcod.console_flush() @LuaEx tcod.console.initRoot(80,50,"The Chronicles Of Doryen v0.1") -- initialize the root console endCredits=false while not tcod.console.isWindowClosed() do -- your game loop -- your game rendering here... -- render transparent credits near the center of the screen if not endCredits then endCredits=tcod.console.renderCredits(35,25,true) end tcod.console.flush() end */ static bool renderCredits(int x, int y, bool alpha); /** @PageName console_credits @FuncTitle Restart the credits animation @FuncDesc When using rederCredits, you can restart the credits animation from the beginning before it's finished by calling this function. @Cpp static void TCODConsole::resetCredits() @C void TCOD_console_credits_reset() @Py console_credits_reset() @C# static void TCODConsole::resetCredits() @Lua tcod.console.resetCredits() */ static void resetCredits(); /** @PageName console_draw @PageTitle Drawing on the root console @PageFather console */ /** @PageName console_draw_basic @PageTitle Basic printing functions @PageFather console_draw @FuncTitle Setting the default background color @FuncDesc This function changes the default background color for a console. The default background color is used by several drawing functions like clear, putChar, ... @Cpp void TCODConsole::setDefaultBackground(TCODColor back) @C void TCOD_console_set_default_background(TCOD_console_t con,TCOD_color_t back) @Py console_set_default_background(con,back) @C# void TCODConsole::setBackgroundColor(TCODColor back) @Lua Console:setBackgroundColor(back) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param back the new default background color for this console @CppEx TCODConsole::root->setDefaultBackground(myColor) @CEx TCOD_console_set_default_background(NULL, my_color) @PyEx litbcod.console_set_default_background(0, my_color) @Lua libtcod.TCODConsole_root:setBackgroundColor( myColor ) */ void setDefaultBackground(TCODColor back); /** @PageName console_draw_basic @FuncTitle Setting the default foreground color @FuncDesc This function changes the default foreground color for a console. The default foreground color is used by several drawing functions like clear, putChar, ... @Cpp void TCODConsole::setDefaultForeground(TCODColor fore) @C void TCOD_console_set_default_foreground(TCOD_console_t con,TCOD_color_t fore) @Py console_set_default_foreground(con, fore) @C# void TCODConsole::setForegroundColor(TCODColor fore) @Lua Console:setForegroundColor(fore) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param fore the new default foreground color for this console @CppEx TCODConsole::root->setDefaultForeground(myColor) @CEx TCOD_console_set_default_foreground(NULL, my_color) @PyEx litbcod.console_set_default_foreground(0, my_color) @LuaEx libtcod.TCODConsole_root:setForegroundColor( myColor ) */ void setDefaultForeground(TCODColor fore); /** @PageName console_draw_basic @FuncTitle Clearing a console @FuncDesc This function modifies all cells of a console : * set the cell's background color to the console default background color * set the cell's foreground color to the console default foreground color * set the cell's ASCII code to 32 (space) @Cpp void TCODConsole::clear() @C void TCOD_console_clear(TCOD_console_t con) @Py console_clear(con) @C# void TCODConsole::clear() @Lua Console:clear() @Param con in the C and Python versions, the offscreen console handler or NULL for the root console */ void clear(); /** @PageName console_draw_basic @FuncTitle Setting the background color of a cell @FuncDesc This function modifies the background color of a cell, leaving other properties (foreground color and ASCII code) unchanged. @Cpp void TCODConsole::setCharBackground(int x, int y, const TCODColor &col, TCOD_bkgnd_flag_t flag = TCOD_BKGND_SET) @C void TCOD_console_set_char_background(TCOD_console_t con,int x, int y, TCOD_color_t col, TCOD_bkgnd_flag_t flag) @Py console_set_char_background(con, x, y, col, flag=BKGND_SET) @C# void TCODConsole::setCharBackground(int x, int y, TCODColor col) void TCODConsole::setCharBackground(int x, int y, TCODColor col, TCODBackgroundFlag flag) @Lua Console:setCharBackground(x, y, col) Console:setCharBackground(x, y, col, flag) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param x,y coordinates of the cell in the console. 0 <= x < console width 0 <= y < console height @Param col the background color to use. You can use color constants @Param flag this flag defines how the cell's background color is modified. See TCOD_bkgnd_flag_t */ void setCharBackground(int x, int y, const TCODColor &col, TCOD_bkgnd_flag_t flag = TCOD_BKGND_SET); /** @PageName console_draw_basic @FuncTitle Setting the foreground color of a cell @FuncDesc This function modifies the foreground color of a cell, leaving other properties (background color and ASCII code) unchanged. @Cpp void TCODConsole::setCharForeground(int x, int y, const TCODColor &col) @C void TCOD_console_set_char_foreground(TCOD_console_t con,int x, int y, TCOD_color_t col) @Py console_set_char_foreground(con, x, y, col) @C# void TCODConsole::setCharForeground(int x, int y, TCODColor col) @Lua Console:setCharForeground(x, y, col) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param x,y coordinates of the cell in the console. 0 <= x < console width 0 <= y < console height @Param col the foreground color to use. You can use color constants */ void setCharForeground(int x, int y, const TCODColor &col); /** @PageName console_draw_basic @FuncTitle Setting the ASCII code of a cell @FuncDesc This function modifies the ASCII code of a cell, leaving other properties (background and foreground colors) unchanged. Note that since a clear console has both background and foreground colors set to black for every cell, using setchar will produce black characters on black background. Use putchar instead. @Cpp void TCODConsole::setChar(int x, int y, int c) @C void TCOD_console_set_char(TCOD_console_t con,int x, int y, int c) @Py console_set_char(con, x, y, c) @C# void TCODConsole::setChar(int x, int y, int c) @Lua Console:setChar(x, y, c) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param x,y coordinates of the cell in the console. 0 <= x < console width 0 <= y < console height @Param c the new ASCII code for the cell. You can use ASCII constants */ void setChar(int x, int y, int c); /** @PageName console_draw_basic @FuncTitle Setting every property of a cell using default colors @FuncDesc This function modifies every property of a cell : * update the cell's background color according to the console default background color (see TCOD_bkgnd_flag_t). * set the cell's foreground color to the console default foreground color * set the cell's ASCII code to c @Cpp void TCODConsole::putChar(int x, int y, int c, TCOD_bkgnd_flag_t flag = TCOD_BKGND_DEFAULT) @C void TCOD_console_put_char(TCOD_console_t con,int x, int y, int c, TCOD_bkgnd_flag_t flag) @Py console_put_char( con, x, y, c, flag=BKGND_DEFAULT) @C# void TCODConsole::putChar(int x, int y, int c) void TCODConsole::putChar(int x, int y, int c, TCODBackgroundFlag flag) @Lua Console:putChar(x, y, c) Console:putChar(x, y, c, flag) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param x,y coordinates of the cell in the console. 0 <= x < console width 0 <= y < console height @Param c the new ASCII code for the cell. You can use ASCII constants @Param flag this flag defines how the cell's background color is modified. See TCOD_bkgnd_flag_t */ void putChar(int x, int y, int c, TCOD_bkgnd_flag_t flag = TCOD_BKGND_DEFAULT); /** @PageName console_draw_basic @FuncTitle Setting every property of a cell using specific colors @FuncDesc This function modifies every property of a cell : * set the cell's background color to back. * set the cell's foreground color to fore. * set the cell's ASCII code to c. @Cpp void TCODConsole::putCharEx(int x, int y, int c, const TCODColor & fore, const TCODColor & back) @C void TCOD_console_put_char_ex(TCOD_console_t con,int x, int y, int c, TCOD_color_t fore, TCOD_color_t back) @Py console_put_char_ex( con, x, y, c, fore, back) @C# void TCODConsole::putCharEx(int x, int y, int c, TCODColor fore, TCODColor back) @Lua Console:putCharEx(x, y, c, fore, back) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param x,y coordinates of the cell in the console. 0 <= x < console width 0 <= y < console height @Param c the new ASCII code for the cell. You can use ASCII constants @Param fore,back new foreground and background colors for this cell */ void putCharEx(int x, int y, int c, const TCODColor &fore, const TCODColor &back); /** @PageName console_bkgnd_flag_t @PageTitle Background effect flags @PageFather console_draw @PageDesc This flag is used by most functions that modify a cell background color. It defines how the console's current background color is used to modify the cell's existing background color : TCOD_BKGND_NONE : the cell's background color is not modified. TCOD_BKGND_SET : the cell's background color is replaced by the console's default background color : newbk = curbk. TCOD_BKGND_MULTIPLY : the cell's background color is multiplied by the console's default background color : newbk = oldbk * curbk TCOD_BKGND_LIGHTEN : newbk = MAX(oldbk,curbk) TCOD_BKGND_DARKEN : newbk = MIN(oldbk,curbk) TCOD_BKGND_SCREEN : newbk = white - (white - oldbk) * (white - curbk) // inverse of multiply : (1-newbk) = (1-oldbk)*(1-curbk) TCOD_BKGND_COLOR_DODGE : newbk = curbk / (white - oldbk) TCOD_BKGND_COLOR_BURN : newbk = white - (white - oldbk) / curbk TCOD_BKGND_ADD : newbk = oldbk + curbk TCOD_BKGND_ADDALPHA(alpha) : newbk = oldbk + alpha*curbk TCOD_BKGND_BURN : newbk = oldbk + curbk - white TCOD_BKGND_OVERLAY : newbk = curbk.x <= 0.5 ? 2*curbk*oldbk : white - 2*(white-curbk)*(white-oldbk) TCOD_BKGND_ALPHA(alpha) : newbk = (1.0f-alpha)*oldbk + alpha*(curbk-oldbk) TCOD_BKGND_DEFAULT : use the console's default background flag Note that TCOD_BKGND_ALPHA and TCOD_BKGND_ADDALPHA are MACROS that needs a float parameter between (0.0 and 1.0). TCOD_BKGND_ALPH and TCOD_BKGND_ADDA should not be used directly (else they will have the same effect as TCOD_BKGND_NONE). For Python, remove TCOD_ : libtcod.BKGND_NONE For C# : None, Set, Multiply, Lighten, Darken, Screen, ColodDodge, ColorBurn, Add, Burn Overlay, Default With lua, use tcod.None, ..., tcod.Default, BUT tcod.console.Alpha(value) and tcod.console.AddAlpha(value) */ /** @PageName console_print @PageTitle String drawing functions @PageFather console_draw @FuncTitle Setting the default background flag @FuncDesc This function defines the background mode (see TCOD_bkgnd_flag_t) for the console. This default mode is used by several functions (print, printRect, ...) @Cpp void TCODConsole::setBackgroundFlag(TCOD_bkgnd_flag_t flag) @C void TCOD_console_set_background_flag(TCOD_console_t con,TCOD_bkgnd_flag_t flag) @Py console_set_background_flag(con, flag) @C# void TCODConsole::setBackgroundFlag(TCODBackgroundFlag flag) @Lua Console:setBackgroundFlag(flag) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param flag this flag defines how the cell's background color is modified. See TCOD_bkgnd_flag_t */ void setBackgroundFlag(TCOD_bkgnd_flag_t flag); /** @PageName console_print @FuncTitle Getting the default background flag @FuncDesc This function returns the background mode (see TCOD_bkgnd_flag_t) for the console. This default mode is used by several functions (print, printRect, ...) @Cpp TCOD_bkgnd_flag_t TCODConsole::getBackgroundFlag() const @C TCOD_bkgnd_flag_t TCOD_console_get_background_flag(TCOD_console_t con) @Py console_get_background_flag(con) @C# TCODBackgroundFlag TCODConsole::getBackgroundFlag() @Lua Console:getBackgroundFlag() @Param con in the C and Python versions, the offscreen console handler or NULL for the root console */ TCOD_bkgnd_flag_t getBackgroundFlag() const; /** @PageName console_print @FuncTitle Setting the default alignment @FuncDesc This function defines the default alignment (see TCOD_alignment_t) for the console. This default alignment is used by several functions (print, printRect, ...). Values for alignment : TCOD_LEFT, TCOD_CENTER, TCOD_RIGHT (in Python, remove TCOD_ : libtcod.LEFT). For C# and Lua : LeftAlignment, RightAlignment, CenterAlignment @Cpp void TCODConsole::setAlignment(TCOD_alignment_t alignment) @C void TCOD_console_set_alignment(TCOD_console_t con,TCOD_bkgnd_flag_t alignment) @Py console_set_alignment(con, alignment) @C# void TCODConsole::setAlignment(TCODAlignment alignment) @Lua Console:setAlignment(alignment) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param alignment defines how the strings are printed on screen. */ void setAlignment(TCOD_alignment_t alignment); /** @PageName console_print @FuncTitle Getting the default alignment @FuncDesc This function returns the default alignment (see TCOD_alignment_t) for the console. This default mode is used by several functions (print, printRect, ...). Values for alignment : TCOD_LEFT, TCOD_CENTER, TCOD_RIGHT (in Python, remove TCOD_ : libtcod.LEFT). For C# and Lua : LeftAlignment, RightAlignment, CenterAlignment @Cpp TCOD_alignment_t TCODConsole::getAlignment() const @C TCOD_alignment_t TCOD_console_get_alignment(TCOD_console_t con) @Py console_get_alignment(con) @C# TCODAlignment TCODConsole::getAlignment() @Lua Console:getAlignment() @Param con in the C and Python versions, the offscreen console handler or NULL for the root console */ TCOD_alignment_t getAlignment() const; /** @PageName console_print @FuncTitle Printing a string with default parameters @FuncDesc This function print a string at a specific position using current default alignment, background flag, foreground and background colors. @Cpp void TCODConsole::print(int x, int y, const char *fmt, ...) @C void TCOD_console_print(TCOD_console_t con,int x, int y, const char *fmt, ...) @Py console_print(con, x, y, fmt) @C# void TCODConsole::print(int x, int y, string fmt) @Lua Console:print(x, y, fmt) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param x,y coordinate of the character in the console, depending on the default alignment for this console : * TCOD_LEFT : leftmost character of the string * TCOD_CENTER : center character of the string * TCOD_RIGHT : rightmost character of the string @Param fmt printf-like format string, eventually followed by parameters. You can use control codes to change the colors inside the string, except in C#. */ void print(int x, int y, const char *fmt, ...); /** @PageName console_print @FuncTitle Printing a string with specific alignment and background mode @FuncDesc This function print a string at a specific position using specific alignment and background flag, but default foreground and background colors. @Cpp void TCODConsole::printEx(int x, int y, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment, const char *fmt, ...) @C void TCOD_console_print_ex(TCOD_console_t con,int x, int y, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment, const char *fmt, ...) @Py console_print_ex(con, x, y, flag, alignment, fmt) @C# void TCODConsole::printEx(int x, int y, TCODBackgroundFlag flag, TCODAlignment alignment, string fmt) @Lua Console::printEx(x, y, flag, alignment, fmt) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param x,y coordinate of the character in the console, depending on the alignment : * TCOD_LEFT : leftmost character of the string * TCOD_CENTER : center character of the string * TCOD_RIGHT : rightmost character of the string @Param flag this flag defines how the cell's background color is modified. See TCOD_bkgnd_flag_t @Param alignment defines how the strings are printed on screen. @Param fmt printf-like format string, eventually followed by parameters. You can use control codes to change the colors inside the string, except in C#. */ void printEx(int x, int y, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment, const char *fmt, ...); /** @PageName console_print @FuncTitle Printing a string with default parameters and autowrap @FuncDesc This function draws a string in a rectangle inside the console, using default colors, alignment and background mode. If the string reaches the borders of the rectangle, carriage returns are inserted. If h > 0 and the bottom of the rectangle is reached, the string is truncated. If h = 0, the string is only truncated if it reaches the bottom of the console. The function returns the height (number of console lines) of the printed string. @Cpp int TCODConsole::printRect(int x, int y, int w, int h, const char *fmt, ...) @C int TCOD_console_print_rect(TCOD_console_t con,int x, int y, int w, int h, const char *fmt, ...) @Py console_print_rect(con, x, y, w, h, fmt) @C# int TCODConsole::printRect(int x, int y, int w, int h, string fmt) @Lua Console:printRect(x, y, w, h, fmt) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param x,y coordinate of the character in the console, depending on the alignment : * TCOD_LEFT : leftmost character of the string * TCOD_CENTER : center character of the string * TCOD_RIGHT : rightmost character of the string @Param w,h size of the rectangle x <= x+w < console width y <= y+h < console height @Param fmt printf-like format string, eventually followed by parameters. You can use control codes to change the colors inside the string, except in C#. */ int printRect(int x, int y, int w, int h, const char *fmt, ...); /** @PageName console_print @FuncTitle Printing a string with specific alignment and background mode and autowrap @FuncDesc This function draws a string in a rectangle inside the console, using default colors, but specific alignment and background mode. If the string reaches the borders of the rectangle, carriage returns are inserted. If h > 0 and the bottom of the rectangle is reached, the string is truncated. If h = 0, the string is only truncated if it reaches the bottom of the console. The function returns the height (number of console lines) of the printed string. @Cpp int TCODConsole::printRectEx(int x, int y, int w, int h, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment, const char *fmt, ...) @C int TCOD_console_print_rect_ex(TCOD_console_t con,int x, int y, int w, int h, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment, const char *fmt, ...) @Py console_print_rect_ex(con, x, y, w, h, flag, alignment, fmt) @C# int TCODConsole::printRectEx(int x, int y, int w, int h, TCODBackgroundFlag flag, TCODAlignment alignment, string fmt) @Lua Console:printRectEx(x, y, w, h, flag, alignment, fmt) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param x,y coordinate of the character in the console, depending on the alignment : * TCOD_LEFT : leftmost character of the string * TCOD_CENTER : center character of the string * TCOD_RIGHT : rightmost character of the string @Param w,h size of the rectangle x <= x+w < console width y <= y+h < console height @Param flag this flag defines how the cell's background color is modified. See TCOD_bkgnd_flag_t @Param alignment defines how the strings are printed on screen. @Param fmt printf-like format string, eventually followed by parameters. You can use control codes to change the colors inside the string, except in C#. */ int printRectEx(int x, int y, int w, int h, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment, const char *fmt, ...); /** @PageName console_print @FuncTitle Compute the height of an autowrapped string @FuncDesc This function returns the expected height of an autowrapped string without actually printing the string with printRect or printRectEx @Cpp int TCODConsole::getHeightRect(int x, int y, int w, int h, const char *fmt, ...) @C int TCOD_console_get_height_rect(TCOD_console_t con,int x, int y, int w, int h, const char *fmt, ...) @Py console_get_height_rect(con, x, y, w, h, fmt) @C# int TCODConsole::getHeightRect(int x, int y, int w, int h, string fmt) @Lua Console:getHeightRect(x, y, w, h, fmt) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param x,y coordinate of the rectangle upper-left corner in the console @Param w,h size of the rectangle x <= x+w < console width y <= y+h < console height @Param fmt printf-like format string, eventually followed by parameters. You can use control codes to change the colors inside the string, except in C#. */ int getHeightRect(int x, int y, int w, int h, const char *fmt, ...); /** @PageName console_print @FuncTitle Changing the colors while printing a string @FuncDesc If you want to draw a string using different colors for each word, the basic solution is to call a string printing function several times, changing the default colors between each call. The TCOD library offers a simpler way to do this, allowing you to draw a string using different colors in a single call. For this, you have to insert color control codes in your string. A color control code is associated with a color set (a foreground color and a background color). If you insert this code in your string, the next characters will use the colors associated with the color control code. There are 5 predefined color control codes : For Python, remove TCOD_ : libtcod.COLCTRL_1 TCOD_COLCTRL_1 TCOD_COLCTRL_2 TCOD_COLCTRL_3 TCOD_COLCTRL_4 TCOD_COLCTRL_5 To associate a color with a code, use setColorControl. To go back to the console's default colors, insert in your string the color stop control code : TCOD_COLCTRL_STOP You can also use any color without assigning it to a control code, using the generic control codes : TCOD_COLCTRL_FORE_RGB TCOD_COLCTRL_BACK_RGB Those controls respectively change the foreground and background color used to print the string characters. In the string, you must insert the r,g,b components of the color (between 1 and 255. The value 0 is forbidden because it represents the end of the string in C/C++) immediately after this code. @Cpp static void TCODConsole::setColorControl(TCOD_colctrl_t con, const TCODColor &fore, const TCODColor &back) @C void TCOD_console_set_color_control(TCOD_colctrl_t con, TCOD_color_t fore, TCOD_color_t back) @Py console_set_color_control(con,fore,back) @C# Not supported directly, use getRGBColorControlString and getColorControlString. @Lua Not supported @Param con the color control TCOD_COLCTRL_x, 1<=x<=5 @Param fore foreground color when this control is activated @Param back background color when this control is activated @CppEx // A string with a red over black word, using predefined color control codes TCODConsole::setColorControl(TCOD_COLCTRL_1,TCODColor::red,TCODColor::black); TCODConsole::root->print(1,1,"String with a %cred%c word.",TCOD_COLCTRL_1,TCOD_COLCTRL_STOP); // A string with a red over black word, using generic color control codes TCODConsole::root->print(1,1,"String with a %c%c%c%c%c%c%c%cred%c word.", TCOD_COLCTRL_FORE_RGB,255,1,1,TCOD_COLCTRL_BACK_RGB,1,1,1,TCOD_COLCTRL_STOP); // A string with a red over black word, using generic color control codes TCODConsole::root->print(1,1,"String with a %c%c%c%c%c%c%c%cred%c word.", TCOD_COLCTRL_FORE_RGB,255,1,1,TCOD_COLCTRL_BACK_RGB,1,1,1,TCOD_COLCTRL_STOP); @CEx // A string with a red over black word, using predefined color control codes TCOD_console_set_color_control(TCOD_COLCTRL_1,red,black); TCOD_console_print(NULL,1,1,"String with a %cred%c word.",TCOD_COLCTRL_1,TCOD_COLCTRL_STOP); // A string with a red word (over default background color), using generic color control codes TCOD_console_print(NULL,1,1,"String with a %c%c%c%cred%c word.", TCOD_COLCTRL_FORE_RGB,255,1,1,TCOD_COLCTRL_STOP); // A string with a red over black word, using generic color control codes TCOD_console_print(NULL,1,1,"String with a %c%c%c%c%c%c%c%cred%c word.", TCOD_COLCTRL_FORE_RGB,255,1,1,TCOD_COLCTRL_BACK_RGB,1,1,1,TCOD_COLCTRL_STOP); @PyEx # A string with a red over black word, using predefined color control codes libtcod.console_set_color_control(libtcod.COLCTRL_1,litbcod.red,litbcod.black) libtcod.console_print(0,1,1,"String with a %cred%c word."%(libtcod.COLCTRL_1,libtcod.COLCTRL_STOP)) # A string with a red word (over default background color), using generic color control codes litbcod.console_print(0,1,1,"String with a %c%c%c%cred%c word."%(libtcod.COLCTRL_FORE_RGB,255,1,1,libtcod.COLCTRL_STOP)) # A string with a red over black word, using generic color control codes libtcod.console_print(0,1,1,"String with a %c%c%c%c%c%c%c%cred%c word."% (libtcod.COLCTRL_FORE_RGB,255,1,1,libtcod.COLCTRL_BACK_RGB,1,1,1,libtcod.COLCTRL_STOP)) @C#Ex TCODConsole.root.print(1,1,String.Format("String with a {0}red{1} word.", TCODConsole.getRGBColorControlString(ColorControlForeground,TCODColor.red), TCODConsole.getColorControlString(ColorControlStop)); */ static void setColorControl(TCOD_colctrl_t con, const TCODColor &fore, const TCODColor &back); #ifndef NO_UNICODE /** @PageName console_print @FuncTitle Unicode functions @FuncDesc those functions are similar to their ASCII equivalent, but work with unicode strings (wchar_t in C/C++). Note that unicode is not supported in the Python wrapper. @Cpp static void TCODConsole::mapStringToFont(const wchar_t *s, int fontCharX, int fontCharY) @C void TCOD_console_map_string_to_font_utf(const wchar_t *s, int fontCharX, int fontCharY) */ static void mapStringToFont(const wchar_t *s, int fontCharX, int fontCharY); /** @PageName console_print @Cpp void TCODConsole::print(int x, int y, const wchar_t *fmt, ...) @C void TCOD_console_print_utf(TCOD_console_t con,int x, int y, const wchar_t *fmt, ...) */ void print(int x, int y, const wchar_t *fmt, ...); /** @PageName console_print @Cpp void TCODConsole::printEx(int x, int y, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment, const wchar_t *fmt, ...) @C void TCOD_console_print_ex_utf(TCOD_console_t con,int x, int y, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment, const wchar_t *fmt, ...) */ void printEx(int x, int y, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment, const wchar_t *fmt, ...); /** @PageName console_print @Cpp int TCODConsole::printRect(int x, int y, int w, int h, const wchar_t *fmt, ...) @C int TCOD_console_print_rect_utf(TCOD_console_t con,int x, int y, int w, int h, const wchar_t *fmt, ...) */ int printRect(int x, int y, int w, int h, const wchar_t *fmt, ...); /** @PageName console_print @Cpp int TCODConsole::printRectEx(int x, int y, int w, int h, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment, const wchar_t *fmt, ...) @C int TCOD_console_print_rect_ex_utf(TCOD_console_t con,int x, int y, int w, int h, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment, const wchar_t *fmt, ...) */ int printRectEx(int x, int y, int w, int h, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment, const wchar_t *fmt, ...); /** @PageName console_print @Cpp int TCODConsole::getHeightRect(int x, int y, int w, int h, const wchar_t *fmt, ...) @C int TCOD_console_get_height_rect_utf(TCOD_console_t con,int x, int y, int w, int h, const wchar_t *fmt, ...) */ int getHeightRect(int x, int y, int w, int h, const wchar_t *fmt, ...); #endif /** @PageName console_advanced @PageFather console_draw @PageTitle Advanced printing functions @FuncTitle Filling a rectangle with the background color @FuncDesc Fill a rectangle inside a console. For each cell in the rectangle : * set the cell's background color to the console default background color * if clear is true, set the cell's ASCII code to 32 (space) @Cpp void TCODConsole::rect(int x, int y, int w, int h, bool clear, TCOD_bkgnd_flag_t flag = TCOD_BKGND_DEFAULT) @C void TCOD_console_rect(TCOD_console_t con,int x, int y, int w, int h, bool clear, TCOD_bkgnd_flag_t flag) @Py console_rect(con,x, y, w, h, clear, flag=BKGND_DEFAULT) @C# void TCODConsole::rect(int x, int y, int w, int h, bool clear) void TCODConsole::rect(int x, int y, int w, int h, bool clear, TCODBackgroundFlag flag) @Lua Console:rect(x, y, w, h, clear) Console:rect(x, y, w, h, clear, flag) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param x,y coordinates of rectangle upper-left corner in the console. 0 <= x < console width 0 <= y < console height @Param w,h size of the rectangle in the console. x <= x+w < console width y <= y+h < console height @Param clear if true, all characters inside the rectangle are set to ASCII code 32 (space). If false, only the background color is modified @Param flag this flag defines how the cell's background color is modified. See TCOD_bkgnd_flag_t */ void rect(int x, int y, int w, int h, bool clear, TCOD_bkgnd_flag_t flag = TCOD_BKGND_DEFAULT); /** @PageName console_advanced @FuncTitle Drawing an horizontal line @FuncDesc Draws an horizontal line in the console, using ASCII code TCOD_CHAR_HLINE (196), and the console's default background/foreground colors. @Cpp void TCODConsole::hline(int x,int y, int l, TCOD_bkgnd_flag_t flag = TCOD_BKGND_DEFAULT) @C void TCOD_console_hline(TCOD_console_t con,int x,int y, int l, TCOD_bkgnd_flag_t flag) @Py console_hline(con,x,y,l,flag=BKGND_DEFAULT) @C# void TCODConsole::hline(int x,int y, int l) void TCODConsole::hline(int x,int y, int l, TCODBackgroundFlag flag) @Lua Console:hline(x,y, l) Console:hline(x,y, l, flag) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param x,y Coordinates of the line's left end in the console. 0 <= x < console width 0 <= y < console height @Param l The length of the line in cells 1 <= l <= console width - x @Param flag this flag defines how the cell's background color is modified. See TCOD_bkgnd_flag_t */ void hline(int x,int y, int l, TCOD_bkgnd_flag_t flag = TCOD_BKGND_DEFAULT); /** @PageName console_advanced @FuncTitle Drawing an vertical line @FuncDesc Draws an vertical line in the console, using ASCII code TCOD_CHAR_VLINE (179), and the console's default background/foreground colors. @Cpp void TCODConsole::vline(int x,int y, int l, TCOD_bkgnd_flag_t flag = TCOD_BKGND_DEFAULT) @C void TCOD_console_vline(TCOD_console_t con,int x,int y, int l, TCOD_bkgnd_flag_t flag) @Py console_vline(con,x,y,l,flag=BKGND_DEFAULT) @C# void TCODConsole::vline(int x,int y, int l) void TCODConsole::vline(int x,int y, int l, TCODBackgroundFlag flag) @Lua Console:vline(x,y, l) Console:vline(x,y, l, flag) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param x,y Coordinates of the line's upper end in the console. 0 <= x < console width 0 <= y < console height @Param l The length of the line in cells 1 <= l <= console height - y @Param flag this flag defines how the cell's background color is modified. See TCOD_bkgnd_flag_t */ void vline(int x,int y, int l, TCOD_bkgnd_flag_t flag = TCOD_BKGND_DEFAULT); /** @PageName console_advanced @FuncTitle Drawing a window frame @FuncDesc This function calls the rect function using the supplied background mode flag, then draws a rectangle with the console's default foreground color. If fmt is not NULL, it is printed on the top of the rectangle, using inverted colors. @Cpp void TCODConsole::printFrame(int x,int y,int w,int h, bool clear=true, TCOD_bkgnd_flag_t flag = TCOD_BKGND_DEFAULT, const char *fmt=NULL, ...) @C void TCOD_console_print_frame(TCOD_console_t con,int x,int y,int w,int h, bool clear, TCOD_bkgnd_flag_t flag, const char *fmt, ...) @Py console_print_frame(con,x, y, w, h, clear=True, flag=BKGND_DEFAULT, fmt=0) @C# void TCODConsole::printFrame(int x,int y, int w,int h) void TCODConsole::printFrame(int x,int y, int w,int h, bool clear) void TCODConsole::printFrame(int x,int y, int w,int h, bool clear, TCODBackgroundFlag flag) void TCODConsole::printFrame(int x,int y, int w,int h, bool clear, TCODBackgroundFlag flag, string fmt) @Lua Console:printFrame(x,y, w,h) Console:printFrame(x,y, w,h, clear) Console:printFrame(x,y, w,h, clear, flag) Console:printFrame(x,y, w,h, clear, flag, fmt) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param x,y Coordinates of the rectangle's upper-left corner in the console. 0 <= x < console width 0 <= y < console height @Param w,h size of the rectangle in the console. x <= x+w < console width y <= y+h < console height @Param clear if true, all characters inside the rectangle are set to ASCII code 32 (space). If false, only the background color is modified @Param flag this flag defines how the cell's background color is modified. See TCOD_bkgnd_flag_t @Param fmt if NULL, the function only draws a rectangle. Else, printf-like format string, eventually followed by parameters. You can use control codes to change the colors inside the string. */ void printFrame(int x,int y,int w,int h, bool clear=true, TCOD_bkgnd_flag_t flag = TCOD_BKGND_DEFAULT, const char *fmt=NULL, ...); /** @PageName console_advanced @FuncTitle Manipulating foreground colors as an image @FuncDesc This function obtains the image containing the console foreground colors. @Cpp TCODImage *TCODConsole::getForegroundImage() @C TCOD_image_t TCOD_console_get_foreground_color_image(TCOD_console_t con) @Py console_get_foreground_image(con) */ TCODImage *getForegroundColorImage(); /** @PageName console_advanced @FuncTitle Manipulating background colors as an image @FuncDesc This function obtains the image containing the console background colors. @Cpp TCODImage *TCODConsole::getBackgroundImage() @C TCOD_image_t TCOD_console_get_background_color_image(TCOD_console_t con) @Py console_get_background_image(con) */ TCODImage *getBackgroundColorImage(); /** @PageName console_read @PageTitle Reading the content of the console @PageFather console_draw @FuncTitle Get the console's width @FuncDesc This function returns the width of a console (either the root console or an offscreen console) @Cpp int TCODConsole::getWidth() const @C int TCOD_console_get_width(TCOD_console_t con) @Py console_get_width(con) @C# int TCODConsole::getWidth() @Lua Console:getWidth() @Param con in the C and Python versions, the offscreen console handler or NULL for the root console */ int getWidth() const; /** @PageName console_read @FuncTitle Get the console's height @FuncDesc This function returns the height of a console (either the root console or an offscreen console) @Cpp int TCODConsole::getHeight() const @C int TCOD_console_get_height(TCOD_console_t con) @Py console_get_height(con) @C# int TCODConsole::getHeight() @Lua Console:getHeight() @Param con in the C and Python versions, the offscreen console handler or NULL for the root console */ int getHeight() const; /** @PageName console_read @FuncTitle Reading the default background color @FuncDesc This function returns the default background color of a console. @Cpp TCODColor TCODConsole::getDefaultBackground() const @C TCOD_color_t TCOD_console_get_default_background(TCOD_console_t con) @Py console_get_default_background(con) @C# TCODColor TCODConsole::getBackgroundColor() @Lua Console:getBackgroundColor() @Param con in the C and Python versions, the offscreen console handler or NULL for the root console */ TCODColor getDefaultBackground() const; /** @PageName console_read @FuncTitle Reading the default foreground color @FuncDesc This function returns the default foreground color of a console. @Cpp TCODColor TCODConsole::getDefaultForeground() const @C TCOD_color_t TCOD_console_get_default_foreground(TCOD_console_t con) @Py console_get_default_foreground(con) @C# TCODColor TCODConsole::getForegroundColor() @Lua Console:getForegroundColor() @Param con in the C and Python versions, the offscreen console handler or NULL for the root console */ TCODColor getDefaultForeground() const; /** @PageName console_read @FuncTitle Reading the background color of a cell @FuncDesc This function returns the background color of a cell. @Cpp TCODColor TCODConsole::getCharBackground(int x, int y) const @C TCOD_color_t TCOD_console_get_char_background(TCOD_console_t con,int x, int y) @Py console_get_char_background(con,x,y) @C# TCODColor TCODConsole::getCharBackground(int x, int y) @Lua Console::getCharBackground(x, y) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param x,y coordinates of the cell in the console. 0 <= x < console width 0 <= y < console height */ TCODColor getCharBackground(int x, int y) const; /** @PageName console_read @FuncTitle Reading the foreground color of a cell @FuncDesc This function returns the foreground color of a cell. @Cpp TCODColor TCODConsole::getCharForeground(int x, int y) const @C TCOD_color_t TCOD_console_get_char_foreground(TCOD_console_t con,int x, int y) @Py console_get_char_foreground(con,x,y) @C# TCODColor TCODConsole::getCharForeground(int x, int y) @Lua Console::getCharForeground(x, y) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param x,y coordinates of the cell in the console. 0 <= x < console width 0 <= y < console height */ TCODColor getCharForeground(int x, int y) const; /** @PageName console_read @FuncTitle Reading the ASCII code of a cell @FuncDesc This function returns the ASCII code of a cell. @Cpp int TCODConsole::getChar(int x, int y) const @C int TCOD_console_get_char(TCOD_console_t con,int x, int y) @Py console_get_char(con,x,y) @C# int TCODConsole::getChar(int x, int y) @Lua Console::getChar(x, y) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param x,y coordinates of the cell in the console. 0 <= x < console width 0 <= y < console height */ int getChar(int x, int y) const; /** @PageName console_fading @PageTitle Screen fading functions @PageFather console_draw @PageDesc Use these functions to easily fade to/from a color @FuncTitle Changing the fading parameters @FuncDesc This function defines the fading parameters, allowing to easily fade the game screen to/from a color. Once they are defined, the fading parameters are valid for ever. You don't have to call setFade for each rendered frame (unless you change the fading parameters). @Cpp static void TCODConsole::setFade(uint8_t fade, const TCODColor &fadingColor) @C void TCOD_console_set_fade(uint8_t fade, TCOD_color_t fadingColor) @Py console_set_fade(fade, fadingColor) @C# static void TCODConsole::setFade(byte fade, TCODColor fadingColor) @Lua tcod.console.setFade(fade, fadingColor) @Param fade the fading amount. 0 => the screen is filled with the fading color. 255 => no fading effect @Param fadingColor the color to use during the console flushing operation @CppEx for (int fade=255; fade >= 0; fade --) { TCODConsole::setFade(fade,TCODColor::black); TCODConsole::flush(); } @CEx int fade; for (fade=255; fade >= 0; fade --) { TCOD_console_setFade(fade,TCOD_black); TCOD_console_flush(); } @PyEx for fade in range(255,0) : libtcod.console_setFade(fade,libtcod.black) libtcod.console_flush() @LuaEx for fade=255,0,-1 do tcod.console.setFade(fade,tcod.color.black) tcod.console.flush() end */ static void setFade(uint8_t fade, const TCODColor &fadingColor); /** @PageName console_fading @FuncTitle Reading the fade amount @FuncDesc This function returns the current fade amount, previously defined by setFade. @Cpp static uint8_t TCODConsole::getFade() @C uint8_t TCOD_console_get_fade() @Py console_get_fade() @C# static byte TCODConsole::getFade() @Lua tcod.console.getFade() */ static uint8_t getFade(); /** @PageName console_fading @FuncTitle Reading the fading color @FuncDesc This function returns the current fading color, previously defined by setFade. @Cpp static TCODColor TCODConsole::getFadingColor() @C TCOD_color_t TCOD_console_get_fading_color() @Py console_get_fading_color() @C# static TCODColor TCODConsole::getFadingColor() @Lua tcod.console.getFadingColor() */ static TCODColor getFadingColor(); /** @PageName console_flush @PageFather console @PageTitle Flushing the root console @FuncDesc Once the root console is initialized, you can use one of the printing functions to change the background colors, the foreground colors or the ASCII characters on the console. Once you've finished rendering the root console, you have to actually apply the updates to the screen with this function. @Cpp static void TCODConsole::flush() @C void TCOD_console_flush() @Py console_flush() @C# static void TCODConsole::flush() @Lua tcod.console.flush() */ static void flush(); /** @PageName console_ascii @PageTitle ASCII constants @PageFather console_draw @FuncDesc Some useful graphic characters in the terminal.bmp font. For the Python version, remove TCOD_ from the constants. C# and Lua is in parenthesis : Single line walls: TCOD_CHAR_HLINE=196 (HorzLine) TCOD_CHAR_VLINE=179 (VertLine) TCOD_CHAR_NE=191 (NE) TCOD_CHAR_NW=218 (NW) TCOD_CHAR_SE=217 (SE) TCOD_CHAR_SW=192 (SW) Double lines walls: TCOD_CHAR_DHLINE=205 (DoubleHorzLine) TCOD_CHAR_DVLINE=186 (DoubleVertLine) TCOD_CHAR_DNE=187 (DoubleNE) TCOD_CHAR_DNW=201 (DoubleNW) TCOD_CHAR_DSE=188 (DoubleSE) TCOD_CHAR_DSW=200 (DoubleSW) Single line vertical/horizontal junctions (T junctions): TCOD_CHAR_TEEW=180 (TeeWest) TCOD_CHAR_TEEE=195 (TeeEast) TCOD_CHAR_TEEN=193 (TeeNorth) TCOD_CHAR_TEES=194 (TeeSouth) Double line vertical/horizontal junctions (T junctions): TCOD_CHAR_DTEEW=185 (DoubleTeeWest) TCOD_CHAR_DTEEE=204 (DoubleTeeEast) TCOD_CHAR_DTEEN=202 (DoubleTeeNorth) TCOD_CHAR_DTEES=203 (DoubleTeeSouth) Block characters: TCOD_CHAR_BLOCK1=176 (Block1) TCOD_CHAR_BLOCK2=177 (Block2) TCOD_CHAR_BLOCK3=178 (Block3) Cross-junction between two single line walls: TCOD_CHAR_CROSS=197 (Cross) Arrows: TCOD_CHAR_ARROW_N=24 (ArrowNorth) TCOD_CHAR_ARROW_S=25 (ArrowSouth) TCOD_CHAR_ARROW_E=26 (ArrowEast) TCOD_CHAR_ARROW_W=27 (ArrowWest) Arrows without tail: TCOD_CHAR_ARROW2_N=30 (ArrowNorthNoTail) TCOD_CHAR_ARROW2_S=31 (ArrowSouthNoTail) TCOD_CHAR_ARROW2_E=16 (ArrowEastNoTail) TCOD_CHAR_ARROW2_W=17 (ArrowWestNoTail) Double arrows: TCOD_CHAR_DARROW_H=29 (DoubleArrowHorz) TCOD_CHAR_ARROW_V=18 (DoubleArrowVert) GUI stuff: TCOD_CHAR_CHECKBOX_UNSET=224 TCOD_CHAR_CHECKBOX_SET=225 TCOD_CHAR_RADIO_UNSET=9 TCOD_CHAR_RADIO_SET=10 Sub-pixel resolution kit: TCOD_CHAR_SUBP_NW=226 (SubpixelNorthWest) TCOD_CHAR_SUBP_NE=227 (SubpixelNorthEast) TCOD_CHAR_SUBP_N=228 (SubpixelNorth) TCOD_CHAR_SUBP_SE=229 (SubpixelSouthEast) TCOD_CHAR_SUBP_DIAG=230 (SubpixelDiagonal) TCOD_CHAR_SUBP_E=231 (SubpixelEast) TCOD_CHAR_SUBP_SW=232 (SubpixelSouthWest) Miscellaneous characters: TCOD_CHAR_SMILY = 1 (Smilie) TCOD_CHAR_SMILY_INV = 2 (SmilieInv) TCOD_CHAR_HEART = 3 (Heart) TCOD_CHAR_DIAMOND = 4 (Diamond) TCOD_CHAR_CLUB = 5 (Club) TCOD_CHAR_SPADE = 6 (Spade) TCOD_CHAR_BULLET = 7 (Bullet) TCOD_CHAR_BULLET_INV = 8 (BulletInv) TCOD_CHAR_MALE = 11 (Male) TCOD_CHAR_FEMALE = 12 (Female) TCOD_CHAR_NOTE = 13 (Note) TCOD_CHAR_NOTE_DOUBLE = 14 (NoteDouble) TCOD_CHAR_LIGHT = 15 (Light) TCOD_CHAR_EXCLAM_DOUBLE = 19 (ExclamationDouble) TCOD_CHAR_PILCROW = 20 (Pilcrow) TCOD_CHAR_SECTION = 21 (Section) TCOD_CHAR_POUND = 156 (Pound) TCOD_CHAR_MULTIPLICATION = 158 (Multiplication) TCOD_CHAR_FUNCTION = 159 (Function) TCOD_CHAR_RESERVED = 169 (Reserved) TCOD_CHAR_HALF = 171 (Half) TCOD_CHAR_ONE_QUARTER = 172 (OneQuarter) TCOD_CHAR_COPYRIGHT = 184 (Copyright) TCOD_CHAR_CENT = 189 (Cent) TCOD_CHAR_YEN = 190 (Yen) TCOD_CHAR_CURRENCY = 207 (Currency) TCOD_CHAR_THREE_QUARTERS = 243 (ThreeQuarters) TCOD_CHAR_DIVISION = 246 (Division) TCOD_CHAR_GRADE = 248 (Grade) TCOD_CHAR_UMLAUT = 249 (Umlaut) TCOD_CHAR_POW1 = 251 (Pow1) TCOD_CHAR_POW3 = 252 (Pow2) TCOD_CHAR_POW2 = 253 (Pow3) TCOD_CHAR_BULLET_SQUARE = 254 (BulletSquare) */ /** @PageName console_input @PageTitle Handling user input @PageDesc The user handling functions allow you to get keyboard and mouse input from the user, either for turn by turn games (the function wait until the user press a key or a mouse button), or real time games (non blocking function). WARNING : those functions also handle screen redraw event, so TCODConsole::flush function won't redraw screen if no user input function is called ! @PageFather console */ /* deprecated as of 1.5.1 */ static TCOD_key_t waitForKeypress(bool flush); /* deprecated as of 1.5.1 */ static TCOD_key_t checkForKeypress(int flags=TCOD_KEY_RELEASED); /** @PageName console_blocking_input @PageCategory Core @PageFather console_input @PageTitle Blocking user input @PageDesc This function stops the application until an event occurs. */ /** @PageName console_non_blocking_input @PageTitle Non blocking user input @PageFather console_input @FuncDesc The preferred way to check for user input is to use checkForEvent below, but you can also get the status of any special key at any time with : @Cpp static bool TCODConsole::isKeyPressed(TCOD_keycode_t key) @C bool TCOD_console_is_key_pressed(TCOD_keycode_t key) @Py console_is_key_pressed(key) @C# static bool TCODConsole::isKeyPressed(TCODKeyCode key) @Lua tcod.console.isKeyPressed(key) @Param key Any key code defined in keycode_t except TCODK_CHAR (Char) and TCODK_NONE (NoKey) */ static bool isKeyPressed(TCOD_keycode_t key); /** @PageName console_key_t @PageTitle Keyboard event structure @PageFather console_input @PageDesc This structure contains information about a key pressed/released by the user. @C typedef struct { TCOD_keycode_t vk; char c; char text[32]; bool pressed; bool lalt; bool lctrl; bool lmeta; bool ralt; bool rctrl; bool rmeta; bool shift; } TCOD_key_t; @Lua key.KeyCode key.Character key.Text key.Pressed key.LeftAlt key.LeftControl key.LeftMeta key.RightAlt key.RightControl key.RightMeta key.Shift @Param vk An arbitrary value representing the physical key on the keyboard. Possible values are stored in the TCOD_keycode_t enum. If no key was pressed, the value is TCODK_NONE @Param c If the key correspond to a printable character, the character is stored in this field. Else, this field contains 0. @Param text If vk is TCODK_TEXT, this will contain the text entered by the user. @Param pressed true if the event is a key pressed, or false for a key released. @Param lalt This field represents the status of the left Alt key : true => pressed, false => released. @Param lctrl This field represents the status of the left Control key : true => pressed, false => released. @Param lmeta This field represents the status of the left Meta (Windows/Command/..) key : true => pressed, false => released. @Param ralt This field represents the status of the right Alt key : true => pressed, false => released. @Param rctrl This field represents the status of the right Control key : true => pressed, false => released. @Param rmeta This field represents the status of the right Meta (Windows/Command/..) key : true => pressed, false => released. @Param shift This field represents the status of the shift key : true => pressed, false => released. */ /** @PageName console_mouse_t @PageTitle Mouse event structure @PageFather console_input @PageDesc This structure contains information about a mouse move/press/release event. @C typedef struct { int x,y; int dx,dy; int cx,cy; int dcx,dcy; bool lbutton; bool rbutton; bool mbutton; bool lbutton_pressed; bool rbutton_pressed; bool mbutton_pressed; bool wheel_up; bool wheel_down; } TCOD_mouse_t; @Param x,y Absolute position of the mouse cursor in pixels relative to the window top-left corner. @Param dx,dy Movement of the mouse cursor since the last call in pixels. @Param cx,cy Coordinates of the console cell under the mouse cursor (pixel coordinates divided by the font size). @Param dcx,dcy Movement of the mouse since the last call in console cells (pixel coordinates divided by the font size). @Param lbutton true if the left button is pressed. @Param rbutton true if the right button is pressed. @Param mbutton true if the middle button (or the wheel) is pressed. @Param lbutton_pressed true if the left button was pressed and released. @Param rbutton_pressed true if the right button was pressed and released. @Param mbutton_pressed true if the middle button was pressed and released. @Param wheel_up true if the wheel was rolled up. @Param wheel_down true if the wheel was rolled down. */ /** @PageName console_keycode_t @PageTitle Key codes @PageFather console_input @PageDesc TCOD_keycode_t is a libtcod specific code representing a key on the keyboard. For Python, replace TCODK by KEY: libtcod.KEY_NONE. C# and Lua, the value is in parenthesis. Possible values are : When no key was pressed (see checkForEvent) : TCOD_NONE (NoKey) Special keys : TCODK_ESCAPE (Escape) TCODK_BACKSPACE (Backspace) TCODK_TAB (Tab) TCODK_ENTER (Enter) TCODK_SHIFT (Shift) TCODK_CONTROL (Control) TCODK_ALT (Alt) TCODK_PAUSE (Pause) TCODK_CAPSLOCK (CapsLock) TCODK_PAGEUP (PageUp) TCODK_PAGEDOWN (PageDown) TCODK_END (End) TCODK_HOME (Home) TCODK_UP (Up) TCODK_LEFT (Left) TCODK_RIGHT (Right) TCODK_DOWN (Down) TCODK_PRINTSCREEN (Printscreen) TCODK_INSERT (Insert) TCODK_DELETE (Delete) TCODK_LWIN (Lwin) TCODK_RWIN (Rwin) TCODK_APPS (Apps) TCODK_KPADD (KeypadAdd) TCODK_KPSUB (KeypadSubtract) TCODK_KPDIV (KeypadDivide) TCODK_KPMUL (KeypadMultiply) TCODK_KPDEC (KeypadDecimal) TCODK_KPENTER (KeypadEnter) TCODK_F1 (F1) TCODK_F2 (F2) TCODK_F3 (F3) TCODK_F4 (F4) TCODK_F5 (F5) TCODK_F6 (F6) TCODK_F7 (F7) TCODK_F8 (F8) TCODK_F9 (F9) TCODK_F10 (F10) TCODK_F11 (F11) TCODK_F12 (F12) TCODK_NUMLOCK (Numlock) TCODK_SCROLLLOCK (Scrolllock) TCODK_SPACE (Space) numeric keys : TCODK_0 (Zero) TCODK_1 (One) TCODK_2 (Two) TCODK_3 (Three) TCODK_4 (Four) TCODK_5 (Five) TCODK_6 (Six) TCODK_7 (Seven) TCODK_8 (Eight) TCODK_9 (Nine) TCODK_KP0 (KeypadZero) TCODK_KP1 (KeypadOne) TCODK_KP2 (KeypadTwo) TCODK_KP3 (KeypadThree) TCODK_KP4 (KeypadFour) TCODK_KP5 (KeypadFive) TCODK_KP6 (KeypadSix) TCODK_KP7 (KeypadSeven) TCODK_KP8 (KeypadEight) TCODK_KP9 (KeypadNine) Any other (printable) key : TCODK_CHAR (Char) Codes starting with TCODK_KP represents keys on the numeric keypad (if available). */ /** @PageName console_offscreen @PageFather console @PageTitle Using off-screen consoles @PageDesc The offscreen consoles allow you to draw on secondary consoles as you would do with the root console. You can then blit those secondary consoles on the root console. This allows you to use local coordinate space while rendering a portion of the final screen, and easily move components of the screen without modifying the rendering functions. @FuncTitle Creating an offscreen console @FuncDesc You can create as many off-screen consoles as you want by using this function. You can draw on them as you would do with the root console, but you cannot flush them to the screen. Else, you can blit them on other consoles, including the root console. See blit. The C version of this function returns a console handler that you can use in most console drawing functions. @Cpp TCODConsole::TCODConsole(int w, int h) @C TCOD_console_t TCOD_console_new(int w, int h) @Py console_new(w,h) @C# TCODConsole::TCODConsole(int w, int h) @Lua tcod.Console(w,h) @Param w,h the console size. 0 < w 0 < h @CppEx // Creating a 40x20 offscreen console, filling it with red and blitting it on the root console at position 5,5 TCODConsole *offscreenConsole = new TCODConsole(40,20); offscreenConsole->setDefaultBackground(TCODColor::red); offscreenConsole->clear(); TCODConsole::blit(offscreenConsole,0,0,40,20,TCODConsole::root,5,5,255); @CEx TCOD_console_t offscreen_console = TCOD_console_new(40,20); TCOD_console_set_default_background(offscreen_console,TCOD_red); TCOD_console_clear(offscreen_console); TCOD_console_blit(offscreen_console,0,0,40,20,NULL,5,5,255); @PyEx offscreen_console = libtcod.console_new(40,20) libtcod.console_set_background_color(offscreen_console,libtcod.red) libtcod.console_clear(offscreen_console) libtcod.console_blit(offscreen_console,0,0,40,20,0,5,5,255) @LuaEx -- Creating a 40x20 offscreen console, filling it with red and blitting it on the root console at position 5,5 offscreenConsole = tcod.Console(40,20) offscreenConsole:setBackgroundColor(tcod.color.red) offscreenConsole:clear() tcod.console.blit(offscreenConsole,0,0,40,20,libtcod.TCODConsole_root,5,5,255) */ TCODConsole(int w, int h); /** @PageName console_offscreen @FuncTitle Creating an offscreen console from a .asc or .apf file @FuncDesc You can create an offscreen console from a file created with Ascii Paint with this constructor @Cpp TCODConsole::TCODConsole(const char *filename) @C TCOD_console_t TCOD_console_from_file(const char *filename) @Param filename path to the .asc or .apf file created with Ascii Paint @CppEx // Creating an offscreen console, filling it with data from the .asc file TCODConsole *offscreenConsole = new TCODConsole("myfile.asc"); @CEx TCOD_console_t offscreen_console = TCOD_console_from_file("myfile.apf"); */ TCODConsole(const char *filename); /** @PageName console_offscreen @FuncTitle Loading an offscreen console from a .asc file @FuncDesc You can load data from a file created with Ascii Paint with this function. When needed, the console will be resized to fit the file size. The function returns false if it couldn't read the file. @Cpp bool TCODConsole::loadAsc(const char *filename) @C bool TCOD_console_load_asc(TCOD_console_t con, const char *filename) @Param con in the C and Python versions, the offscreen console handler @Param filename path to the .asc file created with Ascii Paint @CppEx // Creating a 40x20 offscreen console TCODConsole *offscreenConsole = new TCODConsole(40,20); // possibly resizing it and filling it with data from the .asc file offscreenConsole->loadAsc("myfile.asc"); @CEx TCOD_console_t offscreen_console = TCOD_console_new(40,20); TCOD_console_load_asc(offscreen_console,"myfile.asc"); */ bool loadAsc(const char *filename); /** @PageName console_offscreen @FuncTitle Loading an offscreen console from a .apf file @FuncDesc You can load data from a file created with Ascii Paint with this function. When needed, the console will be resized to fit the file size. The function returns false if it couldn't read the file. @Cpp bool TCODConsole::loadApf(const char *filename) @C bool TCOD_console_load_apf(TCOD_console_t con, const char *filename) @Param con in the C and Python versions, the offscreen console handler @Param filename path to the .apf file created with Ascii Paint @CppEx // Creating a 40x20 offscreen console TCODConsole *offscreenConsole = new TCODConsole(40,20); // possibly resizing it and filling it with data from the .apf file offscreenConsole->loadApf("myfile.apf"); @CEx TCOD_console_t offscreen_console = TCOD_console_new(40,20); TCOD_console_load_apf(offscreen_console,"myfile.asc"); */ bool loadApf(const char *filename); /** @PageName console_offscreen @FuncTitle Saving a console to a .asc file @FuncDesc You can save data from a console to Ascii Paint format with this function. The function returns false if it couldn't write the file. This is the only ASC function that works also with the root console ! @Cpp bool TCODConsole::saveAsc(const char *filename) const @C bool TCOD_console_save_asc(TCOD_console_t con, const char *filename) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param filename path to the .asc file to be created @CppEx console->saveAsc("myfile.asc"); @CEx TCOD_console_save_asc(console,"myfile.asc"); */ bool saveAsc(const char *filename) const; /** @PageName console_offscreen @FuncTitle Saving a console to a .apf file @FuncDesc You can save data from a console to Ascii Paint format with this function. The function returns false if it couldn't write the file. This is the only ASC function that works also with the root console ! @Cpp bool TCODConsole::saveApf(const char *filename) const @C bool TCOD_console_save_apf(TCOD_console_t con, const char *filename) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param filename path to the .apf file to be created @CppEx console->saveApf("myfile.apf"); @CEx TCOD_console_save_apf(console,"myfile.apf"); */ bool saveApf(const char *filename) const; bool loadXp(const char *filename) { return TCOD_console_load_xp(data, filename) != 0; } bool saveXp(const char *filename, int compress_level) { return TCOD_console_save_xp(data, filename, compress_level) != 0; } /** @PageName console_offscreen @FuncTitle Blitting a console on another one @FuncDesc This function allows you to blit a rectangular area of the source console at a specific position on a destination console. It can also simulate alpha transparency with the fade parameter. @Cpp static void blit(const TCODConsole *src,int xSrc, int ySrc, int wSrc, int hSrc, TCODConsole *dst, int xDst, int yDst, float foregroundAlpha=1.0f, float backgroundAlpha=1.0f) @C void TCOD_console_blit(TCOD_console_t src,int xSrc, int ySrc, int wSrc, int hSrc, TCOD_console_t dst, int xDst, int yDst, float foreground_alpha, float background_alpha) @Py console_blit(src,xSrc,ySrc,xSrc,hSrc,dst,xDst,yDst,foregroundAlpha=1.0,backgroundAlpha=1.0) @C# static void TCODConsole::blit(TCODConsole src, int xSrc, int ySrc, int wSrc, int hSrc, TCODConsole dst, int xDst, int yDst) static void TCODConsole::blit(TCODConsole src, int xSrc, int ySrc, int wSrc, int hSrc, TCODConsole dst, int xDst, int yDst, float foreground_alpha) static void TCODConsole::blit(TCODConsole src, int xSrc, int ySrc, int wSrc, int hSrc, TCODConsole dst, int xDst, int yDst, float foreground_alpha, float background_alpha) @Lua tcod.console.blit(src, xSrc, ySrc, wSrc, hSrc, dst, xDst, yDst) tcod.console.blit(src, xSrc, ySrc, wSrc, hSrc, dst, xDst, yDst, foreground_alpha) tcod.console.blit(src, xSrc, ySrc, wSrc, hSrc, dst, xDst, yDst, foreground_alpha, background_alpha) @Param src The source console that must be blitted on another one. @Param xSrc,ySrc,wSrc,hSrc The rectangular area of the source console that will be blitted. If wSrc and/or hSrc == 0, the source console width/height are used @Param dst The destination console. @Param xDst,yDst Where to blit the upper-left corner of the source area in the destination console. @Param foregroundAlpha,backgroundAlpha Alpha transparency of the blitted console. 0.0 => The source console is completely transparent. This function does nothing. 1.0 => The source console is opaque. Its cells replace the destination cells. 0 < fade < 1.0 => The source console is partially blitted, simulating real transparency. @CppEx // Cross-fading between two offscreen consoles. We use two offscreen consoles with the same size as the root console. We render a different screen on each offscreen console. When the user hits a key, we do a cross-fading from the first screen to the second screen. TCODConsole *off1 = new TCODConsole(80,50); TCODConsole *off2 = new TCODConsole(80,50); ... print screen1 on off1 ... print screen2 of off2 // render screen1 in the game window TCODConsole::blit(off1,0,0,80,50,TCODConsole::root,0,0); TCODConsole::flush(); // wait or a keypress TCODConsole::waitForKeypress(true); // do a cross-fading from off1 to off2 for (int i=1; i <= 255; i++) { TCODConsole::blit(off1,0,0,80,50,TCODConsole::root,0,0); // renders the first screen (opaque) TCODConsole::blit(off2,0,0,80,50,TCODConsole::root,0,0,i/255.0,i/255.0); // renders the second screen (transparent) TCODConsole::flush(); } @CEx TCOD_console_t off1 = TCOD_console_new(80,50); TCOD_console_t off2 = TCOD_console_new(80,50); int i; ... print screen1 on off1 ... print screen2 of off2 // render screen1 in the game window TCOD_console_blit(off1,0,0,80,50,NULL,0,0,1.0,1.0); TCOD_console_flush(); // wait or a keypress TCOD_console_wait_for_keypress(true); // do a cross-fading from off1 to off2 for (i=1; i <= 255; i++) { TCOD_console_blit(off1,0,0,80,50,NULL,0,0,1.0,1.0); // renders the first screen (opaque) TCOD_console_blit(off2,0,0,80,50,NULL,0,0,i/255.0,i/255.0); // renders the second screen (transparent) TCOD_console_flush(); } @PyEx off1 = libtcod.console_new(80,50) off2 = libtcod.console_new(80,50) ... print screen1 on off1 ... print screen2 of off2 # render screen1 in the game window libtcod.console_blit(off1,0,0,80,50,0,0,0) libtcod.console_flush() # wait or a keypress libtcod.console_wait_for_keypress(True) # do a cross-fading from off1 to off2 for i in range(1,256) : litbcod.console_blit(off1,0,0,80,50,0,0,0) # renders the first screen (opaque) litbcod.console_blit(off2,0,0,80,50,0,0,0,i/255.0,i/255.0) # renders the second screen (transparent) litbcod.console_flush() @LuaEx -- Cross-fading between two offscreen consoles. We use two offscreen consoles with the same size as the root console. We render a different screen on each offscreen console. When the user hits a key, we do a cross-fading from the first screen to the second screen. off1 = tcod.Console(80,50) off2 = tcod.Console(80,50) ... print screen1 on off1 ... print screen2 of off2 -- render screen1 in the game window root=libtcod.TCODConsole_root tcod.console.blit(off1,0,0,80,50,root,0,0) tcod.console.flush() -- wait or a keypress tcod.console.waitForKeypress(true) -- do a cross-fading from off1 to off2 for i=1,255,1 do tcod.console.blit(off1,0,0,80,50,root,0,0) -- renders the first screen (opaque) tcod.console.blit(off2,0,0,80,50,root,0,0,i/255,i/255) -- renders the second screen (transparent) tcod.console.flush() end */ static void blit(const TCODConsole *src,int xSrc, int ySrc, int wSrc, int hSrc, TCODConsole *dst, int xDst, int yDst, float foreground_alpha=1.0f, float background_alpha=1.0f); /** @PageName console_offscreen @FuncTitle Define a blit-transparent color @FuncDesc This function defines a transparent background color for an offscreen console. All cells with this background color are ignored by the blit operation. You can use it to blit only some parts of the console. @Cpp void TCODConsole::setKeyColor(const TCODColor &col) @C void TCOD_console_set_key_color(TCOD_console_t con,TCOD_color_t col) @Py console_set_key_color(con,col) @C# void TCODConsole::setKeyColor(TCODColor col) @Lua Console:setKeyColor(col) @Param con in the C and Python versions, the offscreen console handler or NULL for the root console @Param col the transparent background color */ void setKeyColor(const TCODColor &col); /** @PageName console_offscreen @FuncTitle Destroying an offscreen console @FuncDesc Use this function to destroy an offscreen console and release any resources allocated. Don't use it on the root console. @Cpp TCODConsole::~TCODConsole() @C void TCOD_console_delete(TCOD_console_t con) @Py console_delete(con) @C# void TCODConsole::Dispose() @Lua through garbage collector @Param con in the C and Python versions, the offscreen console handler @CppEx TCODConsole *off1 = new TCODConsole(80,50); ... use off1 delete off1; // destroy the offscreen console @CEx TCOD_console_t off1 = TCOD_console_new(80,50); ... use off1 TCOD_console_delete(off1); // destroy the offscreen console @PyEx off1 = libtcod.console_new(80,50) ... use off1 libtcod.console_delete(off1) # destroy the offscreen console @LuaEx off1 = tcod.Console(80,50) ... use off1 off1=nil -- release the reference */ virtual ~TCODConsole(); void setDirty(int x, int y, int w, int h); TCODConsole(TCOD_console_t con) : data(con) {} // ctrl = TCOD_COLCTRL_1...TCOD_COLCTRL_5 or TCOD_COLCTRL_STOP static const char *getColorControlString( TCOD_colctrl_t ctrl ); // ctrl = TCOD_COLCTRL_FORE_RGB or TCOD_COLCTRL_BACK_RGB static const char *getRGBColorControlString( TCOD_colctrl_t ctrl, const TCODColor & col ); protected : friend class TCODImage; friend class TCODZip; friend class TCODText; TCODConsole(); TCOD_console_t data; }; #endif /* TCOD_CONSOLE_SUPPORT */ #endif /* _TCOD_CONSOLE_HPP */ libtcod-1.6.4+dfsg/include/console_types.h000066400000000000000000000141201321276576200205540ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_CONSOLE_TYPES_H #define _TCOD_CONSOLE_TYPES_H #include "libtcod_portability.h" typedef void * TCOD_console_t; typedef enum { TCODK_NONE, TCODK_ESCAPE, TCODK_BACKSPACE, TCODK_TAB, TCODK_ENTER, TCODK_SHIFT, TCODK_CONTROL, TCODK_ALT, TCODK_PAUSE, TCODK_CAPSLOCK, TCODK_PAGEUP, TCODK_PAGEDOWN, TCODK_END, TCODK_HOME, TCODK_UP, TCODK_LEFT, TCODK_RIGHT, TCODK_DOWN, TCODK_PRINTSCREEN, TCODK_INSERT, TCODK_DELETE, TCODK_LWIN, TCODK_RWIN, TCODK_APPS, TCODK_0, TCODK_1, TCODK_2, TCODK_3, TCODK_4, TCODK_5, TCODK_6, TCODK_7, TCODK_8, TCODK_9, TCODK_KP0, TCODK_KP1, TCODK_KP2, TCODK_KP3, TCODK_KP4, TCODK_KP5, TCODK_KP6, TCODK_KP7, TCODK_KP8, TCODK_KP9, TCODK_KPADD, TCODK_KPSUB, TCODK_KPDIV, TCODK_KPMUL, TCODK_KPDEC, TCODK_KPENTER, TCODK_F1, TCODK_F2, TCODK_F3, TCODK_F4, TCODK_F5, TCODK_F6, TCODK_F7, TCODK_F8, TCODK_F9, TCODK_F10, TCODK_F11, TCODK_F12, TCODK_NUMLOCK, TCODK_SCROLLLOCK, TCODK_SPACE, TCODK_CHAR, TCODK_TEXT } TCOD_keycode_t; #define TCOD_KEY_TEXT_SIZE 32 /* key data : special code or character or text */ typedef struct { TCOD_keycode_t vk; /* key code */ char c; /* character if vk == TCODK_CHAR else 0 */ char text[TCOD_KEY_TEXT_SIZE]; /* text if vk == TCODK_TEXT else text[0] == '\0' */ bool pressed ; /* does this correspond to a key press or key release event ? */ bool lalt ; bool lctrl ; bool lmeta ; bool ralt ; bool rctrl ; bool rmeta ; bool shift ; } TCOD_key_t; typedef enum { /* single walls */ TCOD_CHAR_HLINE=196, TCOD_CHAR_VLINE=179, TCOD_CHAR_NE=191, TCOD_CHAR_NW=218, TCOD_CHAR_SE=217, TCOD_CHAR_SW=192, TCOD_CHAR_TEEW=180, TCOD_CHAR_TEEE=195, TCOD_CHAR_TEEN=193, TCOD_CHAR_TEES=194, TCOD_CHAR_CROSS=197, /* double walls */ TCOD_CHAR_DHLINE=205, TCOD_CHAR_DVLINE=186, TCOD_CHAR_DNE=187, TCOD_CHAR_DNW=201, TCOD_CHAR_DSE=188, TCOD_CHAR_DSW=200, TCOD_CHAR_DTEEW=185, TCOD_CHAR_DTEEE=204, TCOD_CHAR_DTEEN=202, TCOD_CHAR_DTEES=203, TCOD_CHAR_DCROSS=206, /* blocks */ TCOD_CHAR_BLOCK1=176, TCOD_CHAR_BLOCK2=177, TCOD_CHAR_BLOCK3=178, /* arrows */ TCOD_CHAR_ARROW_N=24, TCOD_CHAR_ARROW_S=25, TCOD_CHAR_ARROW_E=26, TCOD_CHAR_ARROW_W=27, /* arrows without tail */ TCOD_CHAR_ARROW2_N=30, TCOD_CHAR_ARROW2_S=31, TCOD_CHAR_ARROW2_E=16, TCOD_CHAR_ARROW2_W=17, /* double arrows */ TCOD_CHAR_DARROW_H=29, TCOD_CHAR_DARROW_V=18, /* GUI stuff */ TCOD_CHAR_CHECKBOX_UNSET=224, TCOD_CHAR_CHECKBOX_SET=225, TCOD_CHAR_RADIO_UNSET=9, TCOD_CHAR_RADIO_SET=10, /* sub-pixel resolution kit */ TCOD_CHAR_SUBP_NW=226, TCOD_CHAR_SUBP_NE=227, TCOD_CHAR_SUBP_N=228, TCOD_CHAR_SUBP_SE=229, TCOD_CHAR_SUBP_DIAG=230, TCOD_CHAR_SUBP_E=231, TCOD_CHAR_SUBP_SW=232, /* miscellaneous */ TCOD_CHAR_SMILIE = 1, TCOD_CHAR_SMILIE_INV = 2, TCOD_CHAR_HEART = 3, TCOD_CHAR_DIAMOND = 4, TCOD_CHAR_CLUB = 5, TCOD_CHAR_SPADE = 6, TCOD_CHAR_BULLET = 7, TCOD_CHAR_BULLET_INV = 8, TCOD_CHAR_MALE = 11, TCOD_CHAR_FEMALE = 12, TCOD_CHAR_NOTE = 13, TCOD_CHAR_NOTE_DOUBLE = 14, TCOD_CHAR_LIGHT = 15, TCOD_CHAR_EXCLAM_DOUBLE = 19, TCOD_CHAR_PILCROW = 20, TCOD_CHAR_SECTION = 21, TCOD_CHAR_POUND = 156, TCOD_CHAR_MULTIPLICATION = 158, TCOD_CHAR_FUNCTION = 159, TCOD_CHAR_RESERVED = 169, TCOD_CHAR_HALF = 171, TCOD_CHAR_ONE_QUARTER = 172, TCOD_CHAR_COPYRIGHT = 184, TCOD_CHAR_CENT = 189, TCOD_CHAR_YEN = 190, TCOD_CHAR_CURRENCY = 207, TCOD_CHAR_THREE_QUARTERS = 243, TCOD_CHAR_DIVISION = 246, TCOD_CHAR_GRADE = 248, TCOD_CHAR_UMLAUT = 249, TCOD_CHAR_POW1 = 251, TCOD_CHAR_POW3 = 252, TCOD_CHAR_POW2 = 253, TCOD_CHAR_BULLET_SQUARE = 254, /* diacritics */ } TCOD_chars_t; typedef enum { TCOD_COLCTRL_1 = 1, TCOD_COLCTRL_2, TCOD_COLCTRL_3, TCOD_COLCTRL_4, TCOD_COLCTRL_5, TCOD_COLCTRL_NUMBER=5, TCOD_COLCTRL_FORE_RGB, TCOD_COLCTRL_BACK_RGB, TCOD_COLCTRL_STOP } TCOD_colctrl_t; typedef enum { TCOD_BKGND_NONE, TCOD_BKGND_SET, TCOD_BKGND_MULTIPLY, TCOD_BKGND_LIGHTEN, TCOD_BKGND_DARKEN, TCOD_BKGND_SCREEN, TCOD_BKGND_COLOR_DODGE, TCOD_BKGND_COLOR_BURN, TCOD_BKGND_ADD, TCOD_BKGND_ADDA, TCOD_BKGND_BURN, TCOD_BKGND_OVERLAY, TCOD_BKGND_ALPH, TCOD_BKGND_DEFAULT } TCOD_bkgnd_flag_t; typedef enum { TCOD_KEY_PRESSED=1, TCOD_KEY_RELEASED=2, } TCOD_key_status_t; /* custom font flags */ typedef enum { TCOD_FONT_LAYOUT_ASCII_INCOL=1, TCOD_FONT_LAYOUT_ASCII_INROW=2, TCOD_FONT_TYPE_GREYSCALE=4, TCOD_FONT_TYPE_GRAYSCALE=4, TCOD_FONT_LAYOUT_TCOD=8, } TCOD_font_flags_t; typedef enum { TCOD_RENDERER_GLSL, TCOD_RENDERER_OPENGL, TCOD_RENDERER_SDL, TCOD_NB_RENDERERS, } TCOD_renderer_t; typedef enum { TCOD_LEFT, TCOD_RIGHT, TCOD_CENTER } TCOD_alignment_t; #endif /* _TCOD_CONSOLE_TYPES_H */ libtcod-1.6.4+dfsg/include/external/000077500000000000000000000000001321276576200173415ustar00rootroot00000000000000libtcod-1.6.4+dfsg/include/external/pstdint.h000066400000000000000000000747171321276576200212170ustar00rootroot00000000000000/* A portable stdint.h **************************************************************************** * BSD License: **************************************************************************** * * Copyright (c) 2005-2016 Paul Hsieh * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * **************************************************************************** * * Version 0.1.16.0 * * The ANSI C standard committee, for the C99 standard, specified the * inclusion of a new standard include file called stdint.h. This is * a very useful and long desired include file which contains several * very precise definitions for integer scalar types that is critically * important for making several classes of applications portable * including cryptography, hashing, variable length integer libraries * and so on. But for most developers its likely useful just for * programming sanity. * * The problem is that some compiler vendors chose to ignore the C99 * standard and some older compilers have no opportunity to be updated. * Because of this situation, simply including stdint.h in your code * makes it unportable. * * So that's what this file is all about. It's an attempt to build a * single universal include file that works on as many platforms as * possible to deliver what stdint.h is supposed to. Even compilers * that already come with stdint.h can use this file instead without * any loss of functionality. A few things that should be noted about * this file: * * 1) It is not guaranteed to be portable and/or present an identical * interface on all platforms. The extreme variability of the * ANSI C standard makes this an impossibility right from the * very get go. Its really only meant to be useful for the vast * majority of platforms that possess the capability of * implementing usefully and precisely defined, standard sized * integer scalars. Systems which are not intrinsically 2s * complement may produce invalid constants. * * 2) There is an unavoidable use of non-reserved symbols. * * 3) Other standard include files are invoked. * * 4) This file may come in conflict with future platforms that do * include stdint.h. The hope is that one or the other can be * used with no real difference. * * 5) In the current version, if your platform can't represent * int32_t, int16_t and int8_t, it just dumps out with a compiler * error. * * 6) 64 bit integers may or may not be defined. Test for their * presence with the test: #ifdef INT64_MAX or #ifdef UINT64_MAX. * Note that this is different from the C99 specification which * requires the existence of 64 bit support in the compiler. If * this is not defined for your platform, yet it is capable of * dealing with 64 bits then it is because this file has not yet * been extended to cover all of your system's capabilities. * * 7) (u)intptr_t may or may not be defined. Test for its presence * with the test: #ifdef PTRDIFF_MAX. If this is not defined * for your platform, then it is because this file has not yet * been extended to cover all of your system's capabilities, not * because its optional. * * 8) The following might not been defined even if your platform is * capable of defining it: * * WCHAR_MIN * WCHAR_MAX * (u)int64_t * PTRDIFF_MIN * PTRDIFF_MAX * (u)intptr_t * * 9) The following have not been defined: * * WINT_MIN * WINT_MAX * * 10) The criteria for defining (u)int_least(*)_t isn't clear, * except for systems which don't have a type that precisely * defined 8, 16, or 32 bit types (which this include file does * not support anyways). Default definitions have been given. * * 11) The criteria for defining (u)int_fast(*)_t isn't something I * would trust to any particular compiler vendor or the ANSI C * committee. It is well known that "compatible systems" are * commonly created that have very different performance * characteristics from the systems they are compatible with, * especially those whose vendors make both the compiler and the * system. Default definitions have been given, but its strongly * recommended that users never use these definitions for any * reason (they do *NOT* deliver any serious guarantee of * improved performance -- not in this file, nor any vendor's * stdint.h). * * 12) The following macros: * * PRINTF_INTMAX_MODIFIER * PRINTF_INT64_MODIFIER * PRINTF_INT32_MODIFIER * PRINTF_INT16_MODIFIER * PRINTF_LEAST64_MODIFIER * PRINTF_LEAST32_MODIFIER * PRINTF_LEAST16_MODIFIER * PRINTF_INTPTR_MODIFIER * * are strings which have been defined as the modifiers required * for the "d", "u" and "x" printf formats to correctly output * (u)intmax_t, (u)int64_t, (u)int32_t, (u)int16_t, (u)least64_t, * (u)least32_t, (u)least16_t and (u)intptr_t types respectively. * PRINTF_INTPTR_MODIFIER is not defined for some systems which * provide their own stdint.h. PRINTF_INT64_MODIFIER is not * defined if INT64_MAX is not defined. These are an extension * beyond what C99 specifies must be in stdint.h. * * In addition, the following macros are defined: * * PRINTF_INTMAX_HEX_WIDTH * PRINTF_INT64_HEX_WIDTH * PRINTF_INT32_HEX_WIDTH * PRINTF_INT16_HEX_WIDTH * PRINTF_INT8_HEX_WIDTH * PRINTF_INTMAX_DEC_WIDTH * PRINTF_INT64_DEC_WIDTH * PRINTF_INT32_DEC_WIDTH * PRINTF_INT16_DEC_WIDTH * PRINTF_UINT8_DEC_WIDTH * PRINTF_UINTMAX_DEC_WIDTH * PRINTF_UINT64_DEC_WIDTH * PRINTF_UINT32_DEC_WIDTH * PRINTF_UINT16_DEC_WIDTH * PRINTF_UINT8_DEC_WIDTH * * Which specifies the maximum number of characters required to * print the number of that type in either hexadecimal or decimal. * These are an extension beyond what C99 specifies must be in * stdint.h. * * Compilers tested (all with 0 warnings at their highest respective * settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits and 32 * bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual Studio * .net (VC7), Intel C++ 4.0, GNU gcc v3.3.3 * * This file should be considered a work in progress. Suggestions for * improvements, especially those which increase coverage are strongly * encouraged. * * Acknowledgements * * The following people have made significant contributions to the * development and testing of this file: * * Chris Howie * John Steele Scott * Dave Thorup * John Dill * Florian Wobbe * Christopher Sean Morrison * Mikkel Fahnoe Jorgensen * */ #include #include #include /* * For gcc with _STDINT_H, fill in the PRINTF_INT*_MODIFIER macros, and * do nothing else. On the Mac OS X version of gcc this is _STDINT_H_. */ #if ((defined(__SUNPRO_C) && __SUNPRO_C >= 0x570) || (defined(_MSC_VER) && _MSC_VER >= 1600) || (defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (__GNUC__ > 3 || defined(_STDINT_H) || defined(_STDINT_H_) || defined (__UINT_FAST64_TYPE__)) )) && !defined (_PSTDINT_H_INCLUDED) #include #define _PSTDINT_H_INCLUDED # if defined(__GNUC__) && (defined(__x86_64__) || defined(__ppc64__)) && !(defined(__APPLE__) && defined(__MACH__)) # ifndef PRINTF_INT64_MODIFIER # define PRINTF_INT64_MODIFIER "l" # endif # ifndef PRINTF_INT32_MODIFIER # define PRINTF_INT32_MODIFIER "" # endif # else # ifndef PRINTF_INT64_MODIFIER # define PRINTF_INT64_MODIFIER "ll" # endif # ifndef PRINTF_INT32_MODIFIER # if (UINT_MAX == UINT32_MAX) # define PRINTF_INT32_MODIFIER "" # else # define PRINTF_INT32_MODIFIER "l" # endif # endif # endif # ifndef PRINTF_INT16_MODIFIER # define PRINTF_INT16_MODIFIER "h" # endif # ifndef PRINTF_INTMAX_MODIFIER # define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER # endif # ifndef PRINTF_INT64_HEX_WIDTH # define PRINTF_INT64_HEX_WIDTH "16" # endif # ifndef PRINTF_UINT64_HEX_WIDTH # define PRINTF_UINT64_HEX_WIDTH "16" # endif # ifndef PRINTF_INT32_HEX_WIDTH # define PRINTF_INT32_HEX_WIDTH "8" # endif # ifndef PRINTF_UINT32_HEX_WIDTH # define PRINTF_UINT32_HEX_WIDTH "8" # endif # ifndef PRINTF_INT16_HEX_WIDTH # define PRINTF_INT16_HEX_WIDTH "4" # endif # ifndef PRINTF_UINT16_HEX_WIDTH # define PRINTF_UINT16_HEX_WIDTH "4" # endif # ifndef PRINTF_INT8_HEX_WIDTH # define PRINTF_INT8_HEX_WIDTH "2" # endif # ifndef PRINTF_UINT8_HEX_WIDTH # define PRINTF_UINT8_HEX_WIDTH "2" # endif # ifndef PRINTF_INT64_DEC_WIDTH # define PRINTF_INT64_DEC_WIDTH "19" # endif # ifndef PRINTF_UINT64_DEC_WIDTH # define PRINTF_UINT64_DEC_WIDTH "20" # endif # ifndef PRINTF_INT32_DEC_WIDTH # define PRINTF_INT32_DEC_WIDTH "10" # endif # ifndef PRINTF_UINT32_DEC_WIDTH # define PRINTF_UINT32_DEC_WIDTH "10" # endif # ifndef PRINTF_INT16_DEC_WIDTH # define PRINTF_INT16_DEC_WIDTH "5" # endif # ifndef PRINTF_UINT16_DEC_WIDTH # define PRINTF_UINT16_DEC_WIDTH "5" # endif # ifndef PRINTF_INT8_DEC_WIDTH # define PRINTF_INT8_DEC_WIDTH "3" # endif # ifndef PRINTF_UINT8_DEC_WIDTH # define PRINTF_UINT8_DEC_WIDTH "3" # endif # ifndef PRINTF_INTMAX_HEX_WIDTH # define PRINTF_INTMAX_HEX_WIDTH PRINTF_UINT64_HEX_WIDTH # endif # ifndef PRINTF_UINTMAX_HEX_WIDTH # define PRINTF_UINTMAX_HEX_WIDTH PRINTF_UINT64_HEX_WIDTH # endif # ifndef PRINTF_INTMAX_DEC_WIDTH # define PRINTF_INTMAX_DEC_WIDTH PRINTF_UINT64_DEC_WIDTH # endif # ifndef PRINTF_UINTMAX_DEC_WIDTH # define PRINTF_UINTMAX_DEC_WIDTH PRINTF_UINT64_DEC_WIDTH # endif /* * Something really weird is going on with Open Watcom. Just pull some of * these duplicated definitions from Open Watcom's stdint.h file for now. */ # if defined (__WATCOMC__) && __WATCOMC__ >= 1250 # if !defined (INT64_C) # define INT64_C(x) (x + (INT64_MAX - INT64_MAX)) # endif # if !defined (UINT64_C) # define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX)) # endif # if !defined (INT32_C) # define INT32_C(x) (x + (INT32_MAX - INT32_MAX)) # endif # if !defined (UINT32_C) # define UINT32_C(x) (x + (UINT32_MAX - UINT32_MAX)) # endif # if !defined (INT16_C) # define INT16_C(x) (x) # endif # if !defined (UINT16_C) # define UINT16_C(x) (x) # endif # if !defined (INT8_C) # define INT8_C(x) (x) # endif # if !defined (UINT8_C) # define UINT8_C(x) (x) # endif # if !defined (UINT64_MAX) # define UINT64_MAX 18446744073709551615ULL # endif # if !defined (INT64_MAX) # define INT64_MAX 9223372036854775807LL # endif # if !defined (UINT32_MAX) # define UINT32_MAX 4294967295UL # endif # if !defined (INT32_MAX) # define INT32_MAX 2147483647L # endif # if !defined (INTMAX_MAX) # define INTMAX_MAX INT64_MAX # endif # if !defined (INTMAX_MIN) # define INTMAX_MIN INT64_MIN # endif # endif #endif /* * I have no idea what is the truly correct thing to do on older Solaris. * From some online discussions, this seems to be what is being * recommended. For people who actually are developing on older Solaris, * what I would like to know is, does this define all of the relevant * macros of a complete stdint.h? Remember, in pstdint.h 64 bit is * considered optional. */ #if (defined(__SUNPRO_C) && __SUNPRO_C >= 0x420) && !defined(_PSTDINT_H_INCLUDED) #include #define _PSTDINT_H_INCLUDED #endif #ifndef _PSTDINT_H_INCLUDED #define _PSTDINT_H_INCLUDED #ifndef SIZE_MAX # define SIZE_MAX ((size_t)-1) #endif /* * Deduce the type assignments from limits.h under the assumption that * integer sizes in bits are powers of 2, and follow the ANSI * definitions. */ #ifndef UINT8_MAX # define UINT8_MAX 0xff #endif #if !defined(uint8_t) && !defined(_UINT8_T) && !defined(vxWorks) # if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S) typedef unsigned char uint8_t; # define UINT8_C(v) ((uint8_t) v) # else # error "Platform not supported" # endif #endif #ifndef INT8_MAX # define INT8_MAX 0x7f #endif #ifndef INT8_MIN # define INT8_MIN INT8_C(0x80) #endif #if !defined(int8_t) && !defined(_INT8_T) && !defined(vxWorks) # if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S) typedef signed char int8_t; # define INT8_C(v) ((int8_t) v) # else # error "Platform not supported" # endif #endif #ifndef UINT16_MAX # define UINT16_MAX 0xffff #endif #if !defined(uint16_t) && !defined(_UINT16_T) && !defined(vxWorks) #if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S) typedef unsigned int uint16_t; # ifndef PRINTF_INT16_MODIFIER # define PRINTF_INT16_MODIFIER "" # endif # define UINT16_C(v) ((uint16_t) (v)) #elif (USHRT_MAX == UINT16_MAX) typedef unsigned short uint16_t; # define UINT16_C(v) ((uint16_t) (v)) # ifndef PRINTF_INT16_MODIFIER # define PRINTF_INT16_MODIFIER "h" # endif #else #error "Platform not supported" #endif #endif #ifndef INT16_MAX # define INT16_MAX 0x7fff #endif #ifndef INT16_MIN # define INT16_MIN INT16_C(0x8000) #endif #if !defined(int16_t) && !defined(_INT16_T) && !defined(vxWorks) #if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S) typedef signed int int16_t; # define INT16_C(v) ((int16_t) (v)) # ifndef PRINTF_INT16_MODIFIER # define PRINTF_INT16_MODIFIER "" # endif #elif (SHRT_MAX == INT16_MAX) typedef signed short int16_t; # define INT16_C(v) ((int16_t) (v)) # ifndef PRINTF_INT16_MODIFIER # define PRINTF_INT16_MODIFIER "h" # endif #else #error "Platform not supported" #endif #endif #ifndef UINT32_MAX # define UINT32_MAX (0xffffffffUL) #endif #if !defined(uint32_t) && !defined(_UINT32_T) && !defined(vxWorks) #if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S) typedef unsigned long uint32_t; # define UINT32_C(v) v ## UL # ifndef PRINTF_INT32_MODIFIER # define PRINTF_INT32_MODIFIER "l" # endif #elif (UINT_MAX == UINT32_MAX) typedef unsigned int uint32_t; # ifndef PRINTF_INT32_MODIFIER # define PRINTF_INT32_MODIFIER "" # endif # define UINT32_C(v) v ## U #elif (USHRT_MAX == UINT32_MAX) typedef unsigned short uint32_t; # define UINT32_C(v) ((unsigned short) (v)) # ifndef PRINTF_INT32_MODIFIER # define PRINTF_INT32_MODIFIER "" # endif #else #error "Platform not supported" #endif #endif #ifndef INT32_MAX # define INT32_MAX (0x7fffffffL) #endif #ifndef INT32_MIN # define INT32_MIN INT32_C(0x80000000) #endif #if !defined(int32_t) && !defined(_INT32_T) && !defined(vxWorks) #if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S) typedef signed long int32_t; # define INT32_C(v) v ## L # ifndef PRINTF_INT32_MODIFIER # define PRINTF_INT32_MODIFIER "l" # endif #elif (INT_MAX == INT32_MAX) typedef signed int int32_t; # define INT32_C(v) v # ifndef PRINTF_INT32_MODIFIER # define PRINTF_INT32_MODIFIER "" # endif #elif (SHRT_MAX == INT32_MAX) typedef signed short int32_t; # define INT32_C(v) ((short) (v)) # ifndef PRINTF_INT32_MODIFIER # define PRINTF_INT32_MODIFIER "" # endif #else #error "Platform not supported" #endif #endif /* * The macro stdint_int64_defined is temporarily used to record * whether or not 64 integer support is available. It must be * defined for any 64 integer extensions for new platforms that are * added. */ #undef stdint_int64_defined #if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S) # if (__STDC__ && __STDC_VERSION__ >= 199901L) || defined (S_SPLINT_S) # define stdint_int64_defined typedef long long int64_t; typedef unsigned long long uint64_t; # define UINT64_C(v) v ## ULL # define INT64_C(v) v ## LL # ifndef PRINTF_INT64_MODIFIER # define PRINTF_INT64_MODIFIER "ll" # endif # endif #endif #if !defined (stdint_int64_defined) # if defined(__GNUC__) && !defined(vxWorks) # define stdint_int64_defined __extension__ typedef long long int64_t; __extension__ typedef unsigned long long uint64_t; # define UINT64_C(v) v ## ULL # define INT64_C(v) v ## LL # ifndef PRINTF_INT64_MODIFIER # define PRINTF_INT64_MODIFIER "ll" # endif # elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S) # define stdint_int64_defined typedef long long int64_t; typedef unsigned long long uint64_t; # define UINT64_C(v) v ## ULL # define INT64_C(v) v ## LL # ifndef PRINTF_INT64_MODIFIER # define PRINTF_INT64_MODIFIER "ll" # endif # elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC) # define stdint_int64_defined typedef __int64 int64_t; typedef unsigned __int64 uint64_t; # define UINT64_C(v) v ## UI64 # define INT64_C(v) v ## I64 # ifndef PRINTF_INT64_MODIFIER # define PRINTF_INT64_MODIFIER "I64" # endif # endif #endif #if !defined (LONG_LONG_MAX) && defined (INT64_C) # define LONG_LONG_MAX INT64_C (9223372036854775807) #endif #ifndef ULONG_LONG_MAX # define ULONG_LONG_MAX UINT64_C (18446744073709551615) #endif #if !defined (INT64_MAX) && defined (INT64_C) # define INT64_MAX INT64_C (9223372036854775807) #endif #if !defined (INT64_MIN) && defined (INT64_C) # define INT64_MIN INT64_C (-9223372036854775808) #endif #if !defined (UINT64_MAX) && defined (INT64_C) # define UINT64_MAX UINT64_C (18446744073709551615) #endif /* * Width of hexadecimal for number field. */ #ifndef PRINTF_INT64_HEX_WIDTH # define PRINTF_INT64_HEX_WIDTH "16" #endif #ifndef PRINTF_INT32_HEX_WIDTH # define PRINTF_INT32_HEX_WIDTH "8" #endif #ifndef PRINTF_INT16_HEX_WIDTH # define PRINTF_INT16_HEX_WIDTH "4" #endif #ifndef PRINTF_INT8_HEX_WIDTH # define PRINTF_INT8_HEX_WIDTH "2" #endif #ifndef PRINTF_INT64_DEC_WIDTH # define PRINTF_INT64_DEC_WIDTH "19" #endif #ifndef PRINTF_INT32_DEC_WIDTH # define PRINTF_INT32_DEC_WIDTH "10" #endif #ifndef PRINTF_INT16_DEC_WIDTH # define PRINTF_INT16_DEC_WIDTH "5" #endif #ifndef PRINTF_INT8_DEC_WIDTH # define PRINTF_INT8_DEC_WIDTH "3" #endif #ifndef PRINTF_UINT64_DEC_WIDTH # define PRINTF_UINT64_DEC_WIDTH "20" #endif #ifndef PRINTF_UINT32_DEC_WIDTH # define PRINTF_UINT32_DEC_WIDTH "10" #endif #ifndef PRINTF_UINT16_DEC_WIDTH # define PRINTF_UINT16_DEC_WIDTH "5" #endif #ifndef PRINTF_UINT8_DEC_WIDTH # define PRINTF_UINT8_DEC_WIDTH "3" #endif /* * Ok, lets not worry about 128 bit integers for now. Moore's law says * we don't need to worry about that until about 2040 at which point * we'll have bigger things to worry about. */ #ifdef stdint_int64_defined typedef int64_t intmax_t; typedef uint64_t uintmax_t; # define INTMAX_MAX INT64_MAX # define INTMAX_MIN INT64_MIN # define UINTMAX_MAX UINT64_MAX # define UINTMAX_C(v) UINT64_C(v) # define INTMAX_C(v) INT64_C(v) # ifndef PRINTF_INTMAX_MODIFIER # define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER # endif # ifndef PRINTF_INTMAX_HEX_WIDTH # define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH # endif # ifndef PRINTF_INTMAX_DEC_WIDTH # define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH # endif #else typedef int32_t intmax_t; typedef uint32_t uintmax_t; # define INTMAX_MAX INT32_MAX # define UINTMAX_MAX UINT32_MAX # define UINTMAX_C(v) UINT32_C(v) # define INTMAX_C(v) INT32_C(v) # ifndef PRINTF_INTMAX_MODIFIER # define PRINTF_INTMAX_MODIFIER PRINTF_INT32_MODIFIER # endif # ifndef PRINTF_INTMAX_HEX_WIDTH # define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT32_HEX_WIDTH # endif # ifndef PRINTF_INTMAX_DEC_WIDTH # define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT32_DEC_WIDTH # endif #endif /* * Because this file currently only supports platforms which have * precise powers of 2 as bit sizes for the default integers, the * least definitions are all trivial. Its possible that a future * version of this file could have different definitions. */ #ifndef stdint_least_defined typedef int8_t int_least8_t; typedef uint8_t uint_least8_t; typedef int16_t int_least16_t; typedef uint16_t uint_least16_t; typedef int32_t int_least32_t; typedef uint32_t uint_least32_t; # define PRINTF_LEAST32_MODIFIER PRINTF_INT32_MODIFIER # define PRINTF_LEAST16_MODIFIER PRINTF_INT16_MODIFIER # define UINT_LEAST8_MAX UINT8_MAX # define INT_LEAST8_MAX INT8_MAX # define UINT_LEAST16_MAX UINT16_MAX # define INT_LEAST16_MAX INT16_MAX # define UINT_LEAST32_MAX UINT32_MAX # define INT_LEAST32_MAX INT32_MAX # define INT_LEAST8_MIN INT8_MIN # define INT_LEAST16_MIN INT16_MIN # define INT_LEAST32_MIN INT32_MIN # ifdef stdint_int64_defined typedef int64_t int_least64_t; typedef uint64_t uint_least64_t; # define PRINTF_LEAST64_MODIFIER PRINTF_INT64_MODIFIER # define UINT_LEAST64_MAX UINT64_MAX # define INT_LEAST64_MAX INT64_MAX # define INT_LEAST64_MIN INT64_MIN # endif #endif #undef stdint_least_defined /* * The ANSI C committee has defined *int*_fast*_t types as well. This, * of course, defies rationality -- you can't know what will be fast * just from the type itself. Even for a given architecture, compatible * implementations might have different performance characteristics. * Developers are warned to stay away from these types when using this * or any other stdint.h. */ typedef int_least8_t int_fast8_t; typedef uint_least8_t uint_fast8_t; typedef int_least16_t int_fast16_t; typedef uint_least16_t uint_fast16_t; typedef int_least32_t int_fast32_t; typedef uint_least32_t uint_fast32_t; #define UINT_FAST8_MAX UINT_LEAST8_MAX #define INT_FAST8_MAX INT_LEAST8_MAX #define UINT_FAST16_MAX UINT_LEAST16_MAX #define INT_FAST16_MAX INT_LEAST16_MAX #define UINT_FAST32_MAX UINT_LEAST32_MAX #define INT_FAST32_MAX INT_LEAST32_MAX #define INT_FAST8_MIN INT_LEAST8_MIN #define INT_FAST16_MIN INT_LEAST16_MIN #define INT_FAST32_MIN INT_LEAST32_MIN #ifdef stdint_int64_defined typedef int_least64_t int_fast64_t; typedef uint_least64_t uint_fast64_t; # define UINT_FAST64_MAX UINT_LEAST64_MAX # define INT_FAST64_MAX INT_LEAST64_MAX # define INT_FAST64_MIN INT_LEAST64_MIN #endif #undef stdint_int64_defined /* * Whatever piecemeal, per compiler thing we can do about the wchar_t * type limits. */ #if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__) && !defined(vxWorks) # include # ifndef WCHAR_MIN # define WCHAR_MIN 0 # endif # ifndef WCHAR_MAX # define WCHAR_MAX ((wchar_t)-1) # endif #endif /* * Whatever piecemeal, per compiler/platform thing we can do about the * (u)intptr_t types and limits. */ #if (defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED)) || defined (_UINTPTR_T) # define STDINT_H_UINTPTR_T_DEFINED #endif #ifndef STDINT_H_UINTPTR_T_DEFINED # if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64) || defined (__ppc64__) # define stdint_intptr_bits 64 # elif defined (__WATCOMC__) || defined (__TURBOC__) # if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__) # define stdint_intptr_bits 16 # else # define stdint_intptr_bits 32 # endif # elif defined (__i386__) || defined (_WIN32) || defined (WIN32) || defined (__ppc64__) # define stdint_intptr_bits 32 # elif defined (__INTEL_COMPILER) /* TODO -- what did Intel do about x86-64? */ # else /* #error "This platform might not be supported yet" */ # endif # ifdef stdint_intptr_bits # define stdint_intptr_glue3_i(a,b,c) a##b##c # define stdint_intptr_glue3(a,b,c) stdint_intptr_glue3_i(a,b,c) # ifndef PRINTF_INTPTR_MODIFIER # define PRINTF_INTPTR_MODIFIER stdint_intptr_glue3(PRINTF_INT,stdint_intptr_bits,_MODIFIER) # endif # ifndef PTRDIFF_MAX # define PTRDIFF_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX) # endif # ifndef PTRDIFF_MIN # define PTRDIFF_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN) # endif # ifndef UINTPTR_MAX # define UINTPTR_MAX stdint_intptr_glue3(UINT,stdint_intptr_bits,_MAX) # endif # ifndef INTPTR_MAX # define INTPTR_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX) # endif # ifndef INTPTR_MIN # define INTPTR_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN) # endif # ifndef INTPTR_C # define INTPTR_C(x) stdint_intptr_glue3(INT,stdint_intptr_bits,_C)(x) # endif # ifndef UINTPTR_C # define UINTPTR_C(x) stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x) # endif typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t; typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t) intptr_t; # else /* TODO -- This following is likely wrong for some platforms, and does nothing for the definition of uintptr_t. */ typedef ptrdiff_t intptr_t; # endif # define STDINT_H_UINTPTR_T_DEFINED #endif /* * Assumes sig_atomic_t is signed and we have a 2s complement machine. */ #ifndef SIG_ATOMIC_MAX # define SIG_ATOMIC_MAX ((((sig_atomic_t) 1) << (sizeof (sig_atomic_t)*CHAR_BIT-1)) - 1) #endif #endif #if defined (__TEST_PSTDINT_FOR_CORRECTNESS) /* * Please compile with the maximum warning settings to make sure macros are * not defined more than once. */ #include #include #include #define glue3_aux(x,y,z) x ## y ## z #define glue3(x,y,z) glue3_aux(x,y,z) #define DECLU(bits) glue3(uint,bits,_t) glue3(u,bits,) = glue3(UINT,bits,_C) (0); #define DECLI(bits) glue3(int,bits,_t) glue3(i,bits,) = glue3(INT,bits,_C) (0); #define DECL(us,bits) glue3(DECL,us,) (bits) #define TESTUMAX(bits) glue3(u,bits,) = ~glue3(u,bits,); if (glue3(UINT,bits,_MAX) != glue3(u,bits,)) printf ("Something wrong with UINT%d_MAX\n", bits) #define REPORTERROR(msg) { err_n++; if (err_first <= 0) err_first = __LINE__; printf msg; } #define X_SIZE_MAX ((size_t)-1) int main () { int err_n = 0; int err_first = 0; DECL(I,8) DECL(U,8) DECL(I,16) DECL(U,16) DECL(I,32) DECL(U,32) #ifdef INT64_MAX DECL(I,64) DECL(U,64) #endif intmax_t imax = INTMAX_C(0); uintmax_t umax = UINTMAX_C(0); char str0[256], str1[256]; sprintf (str0, "%" PRINTF_INT32_MODIFIER "d", INT32_C(2147483647)); if (0 != strcmp (str0, "2147483647")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str0)); if (atoi(PRINTF_INT32_DEC_WIDTH) != (int) strlen(str0)) REPORTERROR (("Something wrong with PRINTF_INT32_DEC_WIDTH : %s\n", PRINTF_INT32_DEC_WIDTH)); sprintf (str0, "%" PRINTF_INT32_MODIFIER "u", UINT32_C(4294967295)); if (0 != strcmp (str0, "4294967295")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str0)); if (atoi(PRINTF_UINT32_DEC_WIDTH) != (int) strlen(str0)) REPORTERROR (("Something wrong with PRINTF_UINT32_DEC_WIDTH : %s\n", PRINTF_UINT32_DEC_WIDTH)); #ifdef INT64_MAX sprintf (str1, "%" PRINTF_INT64_MODIFIER "d", INT64_C(9223372036854775807)); if (0 != strcmp (str1, "9223372036854775807")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str1)); if (atoi(PRINTF_INT64_DEC_WIDTH) != (int) strlen(str1)) REPORTERROR (("Something wrong with PRINTF_INT64_DEC_WIDTH : %s, %d\n", PRINTF_INT64_DEC_WIDTH, (int) strlen(str1))); sprintf (str1, "%" PRINTF_INT64_MODIFIER "u", UINT64_C(18446744073709550591)); if (0 != strcmp (str1, "18446744073709550591")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str1)); if (atoi(PRINTF_UINT64_DEC_WIDTH) != (int) strlen(str1)) REPORTERROR (("Something wrong with PRINTF_UINT64_DEC_WIDTH : %s, %d\n", PRINTF_UINT64_DEC_WIDTH, (int) strlen(str1))); #endif sprintf (str0, "%d %x\n", 0, ~0); sprintf (str1, "%d %x\n", i8, ~0); if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i8 : %s\n", str1)); sprintf (str1, "%u %x\n", u8, ~0); if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u8 : %s\n", str1)); sprintf (str1, "%d %x\n", i16, ~0); if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i16 : %s\n", str1)); sprintf (str1, "%u %x\n", u16, ~0); if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u16 : %s\n", str1)); sprintf (str1, "%" PRINTF_INT32_MODIFIER "d %x\n", i32, ~0); if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i32 : %s\n", str1)); sprintf (str1, "%" PRINTF_INT32_MODIFIER "u %x\n", u32, ~0); if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u32 : %s\n", str1)); #ifdef INT64_MAX sprintf (str1, "%" PRINTF_INT64_MODIFIER "d %x\n", i64, ~0); if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i64 : %s\n", str1)); #endif sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "d %x\n", imax, ~0); if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with imax : %s\n", str1)); sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "u %x\n", umax, ~0); if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with umax : %s\n", str1)); TESTUMAX(8); TESTUMAX(16); TESTUMAX(32); #ifdef INT64_MAX TESTUMAX(64); #endif #define STR(v) #v #define Q(v) printf ("sizeof " STR(v) " = %u\n", (unsigned) sizeof (v)); if (err_n) { printf ("pstdint.h is not correct. Please use sizes below to correct it:\n"); } Q(int) Q(unsigned) Q(long int) Q(short int) Q(int8_t) Q(int16_t) Q(int32_t) #ifdef INT64_MAX Q(int64_t) #endif #if UINT_MAX < X_SIZE_MAX printf ("UINT_MAX < X_SIZE_MAX\n"); #else printf ("UINT_MAX >= X_SIZE_MAX\n"); #endif printf ("%" PRINTF_INT64_MODIFIER "u vs %" PRINTF_INT64_MODIFIER "u\n", UINT_MAX, X_SIZE_MAX); return EXIT_SUCCESS; } #endif libtcod-1.6.4+dfsg/include/fov.h000066400000000000000000000057651321276576200164770ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_FOV_H #define _TCOD_FOV_H #include "libtcod_portability.h" #include "fov_types.h" #ifdef __cplusplus extern "C" { #endif /* allocate a new map */ TCODLIB_API TCOD_map_t TCOD_map_new(int width, int height); /* set all cells as solid rock (cannot see through nor walk) */ TCODLIB_API void TCOD_map_clear(TCOD_map_t map, bool transparent, bool walkable); /* copy a map to another, reallocating it when needed */ TCODLIB_API void TCOD_map_copy(TCOD_map_t source, TCOD_map_t dest); /* change a cell properties */ TCODLIB_API void TCOD_map_set_properties(TCOD_map_t map, int x, int y, bool is_transparent, bool is_walkable); /* destroy a map */ TCODLIB_API void TCOD_map_delete(TCOD_map_t map); /* calculate the field of view (potentially visible cells from player_x,player_y) */ TCODLIB_API void TCOD_map_compute_fov(TCOD_map_t map, int player_x, int player_y, int max_radius, bool light_walls, TCOD_fov_algorithm_t algo); /* check if a cell is in the last computed field of view */ TCODLIB_API bool TCOD_map_is_in_fov(TCOD_map_t map, int x, int y); TCODLIB_API void TCOD_map_set_in_fov(TCOD_map_t map, int x, int y, bool fov); /* retrieve properties from the map */ TCODLIB_API bool TCOD_map_is_transparent(TCOD_map_t map, int x, int y); TCODLIB_API bool TCOD_map_is_walkable(TCOD_map_t map, int x, int y); TCODLIB_API int TCOD_map_get_width(TCOD_map_t map); TCODLIB_API int TCOD_map_get_height(TCOD_map_t map); TCODLIB_API int TCOD_map_get_nb_cells(TCOD_map_t map); #ifdef __cplusplus } #endif #endif libtcod-1.6.4+dfsg/include/fov.hpp000066400000000000000000000267341321276576200170360ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_FOV_HPP #define _TCOD_FOV_HPP #include "fov.h" class TCODPath; /** @PageName fov @PageCategory Roguelike toolkits @PageTitle Field of view @PageDesc This toolkit allows one to easily calculate the potential visible set of map cells from the player position. A cell is potentially visible if the line of sight from the player to the cell in unobstructed. */ class TCODLIB_API TCODMap { public : /** @PageName fov_init @PageFather fov @PageTitle Building the map @FuncTitle Creating the map object @FuncDesc First, you have to allocate a map of the same size as your dungeon. @Cpp TCODMap::TCODMap (int width, int height) @C TCOD_map_t TCOD_map_new (int width, int height) @Py map_new (width, height) @C# TCODMap::TCODMap(int width, int height) @Param width, height The size of the map (in map cells). */ TCODMap(int width, int height); /** @PageName fov_init @PageFather fov @FuncTitle Defining the cell properties @FuncDesc Then, build your dungeon by defining which cells let the light pass (by default, all cells block the light) and which cells are walkable (by default, all cells are not-walkable). @Cpp void TCODMap::setProperties (int x, int y, bool isTransparent, bool isWalkable) @C void TCOD_map_set_properties (TCOD_map_t map, int x, int y, bool is_transparent, bool is_walkable) @Py map_set_properties (map, x, y, is_transparent, is_walkable) @C# void TCODMap::setProperties (int x, int y, bool isTransparent, bool isWalkable) @Param map In the C version, the map handler returned by the TCOD_map_new function. @Param x, y Coordinate of the cell that we want to update. @Param isTransparent If true, this cell will let the light pass else it will block the light. @Param isWalkable If true, creatures can walk true this cell (it is not a wall). */ void setProperties(int x,int y, bool isTransparent, bool isWalkable); /** @PageName fov_init @PageFather fov @FuncTitle Clearing the map @FuncDesc You can clear an existing map (setting all cells to the chosen walkable/transparent values) with: @Cpp void TCODMap::clear (bool transparent = false, bool walkable = false) @C void TCOD_map_clear (TCOD_map_t map, bool transparent, bool walkable) @Py map_clear (map, transparent = False, walkable = False) @C# void TCODMap::clear() void TCODMap::clear(bool transparent) void TCODMap::clear(bool transparent, bool walkable) @Param map In the C version, the map handler returned by the TCOD_map_new function. @Param walkable Whether the cells should be walkable. @Param transparent Whether the cells should be transparent. */ void clear(bool transparent=false, bool walkable=false); /** @PageName fov_init @PageFather fov @FuncTitle Copying a map @FuncDesc You can copy an existing map into another. You have to allocate the destination map first. @Cpp void TCODMap::copy (const TCODMap * source) @C void TCOD_map_copy (TCOD_map_t source, TCOD_map_t dest) @Py map_copy (source, dest) @C# void TCODMap::copy (TCODMap source) @Param source The map containing the source data. @Param dest In C and Python version, the map where data is copied. @CppEx TCODMap * map = new TCODMap(50,50); // allocate the map map->setProperties(10,10,true,true); // set a cell as 'empty' TCODMap * map2 = new TCODMap(10,10); // allocate another map map2->copy(map); // copy map data into map2, reallocating it to 50x50 @CEx TCOD_map_t map = TCOD_map_new(50,50); TCOD_map_t map2 = TCOD_map_new(10,10); TCOD_map_set_properties(map,10,10,true,true); TCOD_map_copy(map,map2); @PyEx map = libtcod.map_new(50,50) map2 = libtcod.map_new(10,10) libtcod.map_set_properties(map,10,10,True,True) libtcod.map_copy(map,map2) */ void copy (const TCODMap *source); /** @PageName fov_compute @PageTitle Computing the field of view @PageFather fov @FuncDesc Once your map is allocated and empty cells have been defined, you can calculate the field of view with :
typedef enum { FOV_BASIC, 
               FOV_DIAMOND, 
               FOV_SHADOW, 
               FOV_PERMISSIVE_0,FOV_PERMISSIVE_1,FOV_PERMISSIVE_2,FOV_PERMISSIVE_3,
               FOV_PERMISSIVE_4,FOV_PERMISSIVE_5,FOV_PERMISSIVE_6,FOV_PERMISSIVE_7,FOV_PERMISSIVE_8, 
               FOV_RESTRICTIVE,
               NB_FOV_ALGORITHMS } TCOD_fov_algorithm_t;
            
* FOV_BASIC : classic libtcod fov algorithm (ray casted from the player to all the cells on the submap perimeter) * FOV_DIAMOND : based on this algorithm * FOV_SHADOW : based on this algorithm * FOV_PERMISSIVE_x : based on this algorithm Permissive has a variable permissiveness parameter. You can either use the constants FOV_PERMISSIVE_x, x between 0 (the less permissive) and 8 (the more permissive), or using the macro FOV_PERMISSIVE(x). * FOV_RESTRICTIVE : Mingos' Restrictive Precise Angle Shadowcasting (MRPAS). Original implementation here. Comparison of the algorithms : Check this. @Cpp void TCODMap::computeFov(int playerX,int playerY, int maxRadius=0,bool light_walls = true, TCOD_fov_algorithm_t algo = FOV_BASIC) @C void TCOD_map_compute_fov(TCOD_map_t map, int player_x, int player_y, int max_radius, bool light_walls, TCOD_fov_algorithm_t algo) @Py map_compute_fov(map, player_x, player_y, max_radius=0, light_walls=True, algo=FOV_BASIC ) @C# void TCODMap::computeFov(int playerX, int playerY) void TCODMap::computeFov(int playerX, int playerY, int maxRadius) void TCODMap::computeFov(int playerX, int playerY, int maxRadius,bool light_walls) void TCODMap::computeFov(int playerX, int playerY, int maxRadius,bool light_walls, TCODFOVTypes algo) @Param map In the C version, the map handler returned by the TCOD_map_new function. @Param player_x,player_y Position of the player in the map. 0 <= player_x < map width. 0 <= player_y < map height. @Param maxRadius If > 0, the fov is only computed up to maxRadius cells away from the player. Else, the range is unlimited. @Param light_walls Whether the wall cells near ground cells in fov must be in fov too. @Param algo FOV algorithm to use. @CppEx TCODMap *map = new TCODMap(50,50); // allocate the map map->setProperties(10,10,true,true); // set a cell as 'empty' map->computeFov(10,10); // calculate fov from the cell 10x10 (basic raycasting, unlimited range, walls lighting on) @CEx TCOD_map_t map = TCOD_map_new(50,50); TCOD_map_set_properties(map,10,10,true,true); TCOD_map_compute_fov(map,10,10,0,true,FOV_SHADOW); // using shadow casting @PyEx map = libtcod.map_new(50,50) libtcod.map_set_properties(map,10,10,True,True) libtcod.map_compute_fov(map,10,10,0,True,libtcod.FOV_PERMISSIVE(2)) */ void computeFov(int playerX,int playerY, int maxRadius = 0,bool light_walls = true, TCOD_fov_algorithm_t algo = FOV_BASIC); /** @PageName fov_get @PageFather fov @PageTitle Reading fov information @FuncTitle Checking if a cell is in fov @FuncDesc Once your computed the field of view, you can know if a cell is visible with : @Cpp bool TCODMap::isInFov(int x, int y) const @C bool TCOD_map_is_in_fov(TCOD_map_t map, int x, int y) @Py map_is_in_fov(map, x, y) @C# bool TCODMap::isInFov(int x, int y) @Param map In the C version, the map handler returned by the TCOD_map_new function. @Param x,y Coordinates of the cell we want to check. 0 <= x < map width. 0 <= y < map height. @CppEx TCODMap *map = new TCODMap(50,50); // allocate the map map->setProperties(10,10,true,true); // set a cell as 'empty' map->computeFov(10,10); // calculate fov from the cell 10x10 bool visible=map->isInFov(10,10); // is the cell 10x10 visible ? @CEx TCOD_map_t map = TCOD_map_new(50,50); TCOD_map_set_properties(map,10,10,true,true); TCOD_map_compute_fov(map,10,10); bool visible = TCOD_map_is_in_fov(map,10,10); @PyEx map = libtcod.map_new(50,50) libtcod.map_set_properties(map,10,10,True,True) libtcod.map_compute_fov(map,10,10) visible = libtcod.map_is_in_fov(map,10,10) */ bool isInFov(int x,int y) const; /** @PageName fov_get @FuncTitle Checking a cell transparency/walkability @FuncDesc You can also retrieve transparent/walkable information with : @Cpp bool TCODMap::isTransparent(int x, int y) const bool TCODMap::isWalkable(int x, int y) const @C bool TCOD_map_is_transparent(TCOD_map_t map, int x, int y) bool TCOD_map_is_walkable(TCOD_map_t map, int x, int y) @Py map_is_transparent(map, x, y) map_is_walkable(map, x, y) @C# bool TCODMap::isTransparent(int x, int y) bool TCODMap::isWalkable(int x, int y) @Param map In the C version, the map handler returned by the TCOD_map_new function. @Param x,y Coordinates of the cell we want to check. 0 <= x < map width. 0 <= y < map height. */ bool isTransparent(int x, int y) const; bool isWalkable(int x, int y) const; /** @PageName fov_get @FuncTitle Getting the map size @FuncDesc You can retrieve the map size with : @Cpp int TCODMap::getWidth() const int TCODMap::getHeight() const @C int TCOD_map_get_width(TCOD_map_t map) int TCOD_map_get_height(TCOD_map_t map) @Py map_get_width(map) map_get_height(map) @C# int TCODMap::getWidth() int TCODMap::getHeight() @Param map In the C version, the map handler returned by the TCOD_map_new function. */ int getWidth() const; int getHeight() const; virtual ~TCODMap(); void setInFov(int x,int y, bool fov); int getNbCells() const; friend class TCODLIB_API TCODPath; friend class TCODLIB_API TCODDijkstra; // protected : TCOD_map_t data; }; #endif libtcod-1.6.4+dfsg/include/fov_types.h000066400000000000000000000047721321276576200177200ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_FOV_TYPES_H #define _TCOD_FOV_TYPES_H #ifdef __cplusplus extern "C" { #endif typedef void *TCOD_map_t; /* FOV_BASIC : http://roguebasin.roguelikedevelopment.org/index.php?title=Ray_casting FOV_DIAMOND : http://www.geocities.com/temerra/los_rays.html FOV_SHADOW : http://roguebasin.roguelikedevelopment.org/index.php?title=FOV_using_recursive_shadowcasting FOV_PERMISSIVE : http://roguebasin.roguelikedevelopment.org/index.php?title=Precise_Permissive_Field_of_View FOV_RESTRICTIVE : Mingos' Restrictive Precise Angle Shadowcasting (contribution by Mingos) */ typedef enum { FOV_BASIC, FOV_DIAMOND, FOV_SHADOW, FOV_PERMISSIVE_0, FOV_PERMISSIVE_1, FOV_PERMISSIVE_2, FOV_PERMISSIVE_3, FOV_PERMISSIVE_4, FOV_PERMISSIVE_5, FOV_PERMISSIVE_6, FOV_PERMISSIVE_7, FOV_PERMISSIVE_8, FOV_RESTRICTIVE, NB_FOV_ALGORITHMS } TCOD_fov_algorithm_t; #define FOV_PERMISSIVE(x) ((TCOD_fov_algorithm_t)(FOV_PERMISSIVE_0 + (x))) #ifdef __cplusplus } #endif #endif /* _TCOD_FOV_TYPES_H */ libtcod-1.6.4+dfsg/include/gui/000077500000000000000000000000001321276576200163035ustar00rootroot00000000000000libtcod-1.6.4+dfsg/include/gui/button.hpp000066400000000000000000000043031321276576200203270ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TCOD_GUI_BUTTON_HPP #define TCOD_GUI_BUTTON_HPP #include "widget.hpp" class TCODLIB_GUI_API Button : public Widget { public : Button(const char *label, const char *tip, widget_callback_t cbk, void *userData=NULL); Button(int x, int y, int width, int height, const char *label, const char *tip, widget_callback_t cbk, void *userData=NULL); virtual ~Button(); void render(); void setLabel(const char *newLabel); void computeSize(); inline bool isPressed() { return pressed; } protected : bool pressed; char *label; widget_callback_t cbk; void onButtonPress(); void onButtonRelease(); void onButtonClick(); void expand(int width, int height); }; #endif /* TCOD_GUI_BUTTON_HPP */ libtcod-1.6.4+dfsg/include/gui/container.hpp000066400000000000000000000037261321276576200210060ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TCOD_GUI_CONTAINER_HPP #define TCOD_GUI_CONTAINER_HPP #include "widget.hpp" class TCODLIB_GUI_API Container : public Widget { public : Container(int x, int y, int w, int h) : Widget(x,y,w,h) {} virtual ~Container(); void addWidget(Widget *wid); void removeWidget(Widget *wid); void setVisible(bool val); void render(); void clear(); void update(const TCOD_key_t k); protected : TCODList content; }; #endif /* TCOD_GUI_CONTAINER_HPP */ libtcod-1.6.4+dfsg/include/gui/flatlist.hpp000066400000000000000000000044001321276576200206340ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TCOD_GUI_FLATLIST_HPP #define TCOD_GUI_FLATLIST_HPP #include "textbox.hpp" class TCODLIB_GUI_API FlatList : public TextBox { public : FlatList(int x,int y,int w, const char **list, const char *label, const char *tip=NULL); virtual ~FlatList(); void render(); void update(const TCOD_key_t k); void setCallback(void (*cbk)(Widget *wid, const char * val, void *data), void *data) { this->cbk=cbk; this->data=data;} void setValue(const char * value); void setList(const char **list); protected : const char **value; const char **list; bool onLeftArrow; bool onRightArrow; void (*cbk)(Widget *wid, const char *val, void *data); void *data; void valueToText(); void textToValue(); void onButtonClick(); }; #endif /* TCOD_GUI_FLATLIST_HPP */ libtcod-1.6.4+dfsg/include/gui/gui.hpp000066400000000000000000000036171321276576200176070ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _GUI_HPP #define _GUI_HPP #include "libtcod.hpp" #include "widget.hpp" #include "button.hpp" #include "radiobutton.hpp" #include "container.hpp" #include "label.hpp" #include "statusbar.hpp" #include "textbox.hpp" #include "flatlist.hpp" #include "slider.hpp" #include "togglebutton.hpp" #include "toolbar.hpp" #include "vbox.hpp" #include "hbox.hpp" #include "image.hpp" #endif libtcod-1.6.4+dfsg/include/gui/gui_portability.hpp000066400000000000000000000037101321276576200222230ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TCOD_GUI_PORTABILITY_HPP #define TCOD_GUI_PORTABILITY_HPP #include "../libtcod_portability.h" #ifdef TCOD_VISUAL_STUDIO #pragma warning(disable:4996) #pragma warning(disable:4251) #endif // DLL export #ifdef TCOD_WINDOWS #ifdef LIBTCOD_GUI_EXPORTS #define TCODLIB_GUI_API __declspec(dllexport) #else #define TCODLIB_GUI_API __declspec(dllimport) #endif #else #define TCODLIB_GUI_API #endif #endif /* TCOD_GUI_PORTABILITY_HPP */ libtcod-1.6.4+dfsg/include/gui/hbox.hpp000066400000000000000000000033351321276576200177600ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TCOD_GUI_HBOX_HPP #define TCOD_GUI_HBOX_HPP #include "vbox.hpp" class TCODLIB_GUI_API HBox : public VBox { public : HBox(int x, int y, int padding); void computeSize(); }; #endif /* TCOD_GUI_HBOX_HPP */ libtcod-1.6.4+dfsg/include/gui/image.hpp000066400000000000000000000035741321276576200201070ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TCOD_GUI_IMAGE_HPP #define TCOD_GUI_IMAGE_HPP #include "widget.hpp" class TCODLIB_GUI_API Image : public Widget { public : Image(int x,int y,int w, int h, const char *tip=NULL); virtual ~Image(); void setBackgroundColor(const TCODColor col); void render(); protected : void expand(int width, int height); TCODColor back; }; #endif /* TCOD_GUI_IMAGE_HPP */ libtcod-1.6.4+dfsg/include/gui/label.hpp000066400000000000000000000036221321276576200200760ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TCOD_GUI_LABEL_HPP #define TCOD_GUI_LABEL_HPP #include "widget.hpp" class TCODLIB_GUI_API Label : public Widget { public : Label(int x, int y, const char *label, const char *tip=NULL ); void render(); void computeSize(); void setValue(const char *label) { this->label=label; } protected : const char *label; void expand(int width, int height); }; #endif /* TCOD_GUI_LABEL_HPP */ libtcod-1.6.4+dfsg/include/gui/radiobutton.hpp000066400000000000000000000045461321276576200213570ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TCOD_GUI_RADIOBUTTON_HPP #define TCOD_GUI_RADIOBUTTON_HPP #include "button.hpp" class TCODLIB_GUI_API RadioButton : public Button { public : RadioButton(const char *label, const char *tip, widget_callback_t cbk, void *userData=NULL) : Button(label,tip,cbk,userData),group(defaultGroup) {} RadioButton(int x, int y, int width, int height, const char *label, const char *tip, widget_callback_t cbk, void *userData=NULL) : Button(x,y,width,height,label,tip,cbk,userData),group(defaultGroup) {} void setGroup(int group) { this->group=group; } void render(); void select(); void unSelect(); static void unSelectGroup(int group); static void setDefaultGroup(int group) { defaultGroup=group; } protected : static int defaultGroup; int group; static RadioButton *groupSelect[512]; void onButtonClick(); }; #endif /* TCOD_GUI_RADIOBUTTON_HPP */ libtcod-1.6.4+dfsg/include/gui/slider.hpp000066400000000000000000000046611321276576200203050ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TCOD_GUI_SLIDER_HPP #define TCOD_GUI_SLIDER_HPP #include "textbox.hpp" class TCODLIB_GUI_API Slider : public TextBox { public : Slider(int x,int y,int w, float min, float max, const char *label, const char *tip=NULL); virtual ~Slider(); void render(); void update(const TCOD_key_t k); void setMinMax(float min, float max) { this->min=min;this->max=max; } void setCallback(void (*cbk)(Widget *wid, float val, void *data), void *data) { this->cbk=cbk; this->data=data;} void setFormat(const char *fmt); void setValue(float value); void setSensitivity(float sensitivity) { this->sensitivity=sensitivity;} protected : float min,max,value,sensitivity; bool onArrows; bool drag; int dragx; int dragy; float dragValue; char *fmt; void (*cbk)(Widget *wid, float val, void *data); void *data; void valueToText(); void textToValue(); void onButtonPress(); void onButtonRelease(); }; #endif /* TCOD_GUI_SLIDER_HPP */ libtcod-1.6.4+dfsg/include/gui/statusbar.hpp000066400000000000000000000034061321276576200210270ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TCOD_GUI_STATUSBAR_HPP #define TCOD_GUI_STATUSBAR_HPP #include "widget.hpp" class TCODLIB_GUI_API StatusBar : public Widget { public : StatusBar(int x,int y,int w, int h):Widget(x,y,w,h) {} void render(); }; #endif /* TCOD_GUI_STATUSBAR_HPP */ libtcod-1.6.4+dfsg/include/gui/textbox.hpp000066400000000000000000000044771321276576200205250ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TCOD_GUI_TEXTBOX_HPP #define TCOD_GUI_TEXTBOX_HPP #include "widget.hpp" class TCODLIB_GUI_API TextBox : public Widget { public : TextBox(int x,int y,int w, int maxw, const char *label, const char *value, const char *tip=NULL); virtual ~TextBox(); void render(); void update(const TCOD_key_t k); void setText(const char *txt); const char *getValue() { return txt; } void setCallback(void (*cbk)(Widget *wid, char * val, void * data), void *data) { txtcbk=cbk; this->data=data; } static void setBlinkingDelay(float delay) { blinkingDelay=delay; } protected : static float blinkingDelay; char *label; char *txt; float blink; int pos, offset; int boxx,boxw,maxw; bool insert; void (*txtcbk)(Widget *wid, char * val, void *data); void *data; void onButtonClick(); }; #endif /* TCOD_GUI_TEXTBOX_HPP */ libtcod-1.6.4+dfsg/include/gui/togglebutton.hpp000066400000000000000000000043051321276576200215330ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TCOD_GUI_TOGGLEBUTTON_HPP #define TCOD_GUI_TOGGLEBUTTON_HPP #include "button.hpp" class TCODLIB_GUI_API ToggleButton : public Button { public : ToggleButton(const char *label, const char *tip, widget_callback_t cbk, void *userData=NULL) :Button(label, tip, cbk, userData) {} ToggleButton(int x, int y, int width, int height, const char *label, const char *tip, widget_callback_t cbk, void *userData=NULL) :Button(x, y, width, height, label, tip, cbk, userData) {} void render(); bool isPressed() { return pressed; } void setPressed(bool val) { pressed=val; } protected : void onButtonPress(); void onButtonRelease(); void onButtonClick(); }; #endif /* TCOD_GUI_TOGGLEBUTTON_HPP */ libtcod-1.6.4+dfsg/include/gui/toolbar.hpp000066400000000000000000000037731321276576200204700ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TCOD_GUI_TOOLBAR_HPP #define TCOD_GUI_TOOLBAR_HPP #include "container.hpp" class TCODLIB_GUI_API ToolBar : public Container { public : ToolBar(int x, int y, const char *name, const char *tip=NULL); ToolBar(int x, int y, int w, const char *name, const char *tip=NULL); ~ToolBar(); void render(); void setName(const char *name); void addSeparator(const char *txt, const char *tip=NULL); void computeSize(); protected : char *name; int fixedWidth; }; #endif /* TCOD_GUI_TOOLBAR_HPP */ libtcod-1.6.4+dfsg/include/gui/vbox.hpp000066400000000000000000000034511321276576200177750ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TCOD_GUI_VBOX_HPP #define TCOD_GUI_VBOX_HPP #include "container.hpp" class TCODLIB_GUI_API VBox : public Container { public : VBox(int x, int y, int padding) : Container(x,y,0,0),padding(padding) {} void computeSize(); protected : int padding; }; #endif /* TCOD_GUI_VBOX_HPP */ libtcod-1.6.4+dfsg/include/gui/widget.hpp000066400000000000000000000062501321276576200203020ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TCOD_GUI_WIDGET_HPP #define TCOD_GUI_WIDGET_HPP #include "gui_portability.hpp" #include "../color.hpp" #include "../console.hpp" #include "../list.hpp" #include "../mouse.hpp" class TCODLIB_GUI_API Widget { public : int x,y,w,h; void *userData; static Widget *focus; static Widget *keyboardFocus; Widget(); Widget(int x, int y); Widget(int x, int y, int w, int h); virtual ~Widget(); virtual void render() {} virtual void update(const TCOD_key_t k); void move(int x,int y); void setTip(const char *tip); virtual void setVisible(bool val) { visible=val; } bool isVisible() { return visible; } virtual void computeSize() {} static void setBackgroundColor(const TCODColor col,const TCODColor colFocus); static void setForegroundColor(const TCODColor col,const TCODColor colFocus); static void setConsole(TCODConsole *con); static void updateWidgets(const TCOD_key_t k,const TCOD_mouse_t mouse); static void renderWidgets(); static TCOD_mouse_t mouse; static TCODColor fore; virtual void expand(int width, int height) {} protected : friend class StatusBar; friend class ToolBar; friend class VBox; friend class HBox; virtual void onMouseIn() {} virtual void onMouseOut() {} virtual void onButtonPress() {} virtual void onButtonRelease() {} virtual void onButtonClick() {} static void updateWidgetsIntern(const TCOD_key_t k); static float elapsed; static TCODColor back; static TCODColor backFocus; static TCODColor foreFocus; static TCODConsole *con; static TCODList widgets; char *tip; bool mouseIn:1; bool mouseL:1; bool visible:1; }; typedef void (*widget_callback_t) ( Widget *w, void *userData ); #endif /* TCOD_GUI_WIDGET_HPP */ libtcod-1.6.4+dfsg/include/heightmap.h000066400000000000000000000120111321276576200176310ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_HEIGHTMAP_H #define _TCOD_HEIGHTMAP_H #include "libtcod_portability.h" #include "mersenne_types.h" #include "noise.h" #ifdef __cplusplus extern "C" { #endif typedef struct { int w,h; float *values; } TCOD_heightmap_t; TCODLIB_API TCOD_heightmap_t *TCOD_heightmap_new(int w,int h); TCODLIB_API void TCOD_heightmap_delete(TCOD_heightmap_t *hm); TCODLIB_API float TCOD_heightmap_get_value(const TCOD_heightmap_t *hm, int x, int y); TCODLIB_API float TCOD_heightmap_get_interpolated_value(const TCOD_heightmap_t *hm, float x, float y); TCODLIB_API void TCOD_heightmap_set_value(TCOD_heightmap_t *hm, int x, int y, float value); TCODLIB_API float TCOD_heightmap_get_slope(const TCOD_heightmap_t *hm, int x, int y); TCODLIB_API void TCOD_heightmap_get_normal(const TCOD_heightmap_t *hm, float x, float y, float n[3], float waterLevel); TCODLIB_API int TCOD_heightmap_count_cells(const TCOD_heightmap_t *hm, float min, float max); TCODLIB_API bool TCOD_heightmap_has_land_on_border(const TCOD_heightmap_t *hm, float waterLevel); TCODLIB_API void TCOD_heightmap_get_minmax(const TCOD_heightmap_t *hm, float *min, float *max); TCODLIB_API void TCOD_heightmap_copy(const TCOD_heightmap_t *hm_source,TCOD_heightmap_t *hm_dest); TCODLIB_API void TCOD_heightmap_add(TCOD_heightmap_t *hm, float value); TCODLIB_API void TCOD_heightmap_scale(TCOD_heightmap_t *hm, float value); TCODLIB_API void TCOD_heightmap_clamp(TCOD_heightmap_t *hm, float min, float max); TCODLIB_API void TCOD_heightmap_normalize(TCOD_heightmap_t *hm, float min, float max); TCODLIB_API void TCOD_heightmap_clear(TCOD_heightmap_t *hm); TCODLIB_API void TCOD_heightmap_lerp_hm(const TCOD_heightmap_t *hm1, const TCOD_heightmap_t *hm2, TCOD_heightmap_t *hmres, float coef); TCODLIB_API void TCOD_heightmap_add_hm(const TCOD_heightmap_t *hm1, const TCOD_heightmap_t *hm2, TCOD_heightmap_t *hmres); TCODLIB_API void TCOD_heightmap_multiply_hm(const TCOD_heightmap_t *hm1, const TCOD_heightmap_t *hm2, TCOD_heightmap_t *hmres); TCODLIB_API void TCOD_heightmap_add_hill(TCOD_heightmap_t *hm, float hx, float hy, float hradius, float hheight); TCODLIB_API void TCOD_heightmap_dig_hill(TCOD_heightmap_t *hm, float hx, float hy, float hradius, float hheight); TCODLIB_API void TCOD_heightmap_dig_bezier(TCOD_heightmap_t *hm, int px[4], int py[4], float startRadius, float startDepth, float endRadius, float endDepth); TCODLIB_API void TCOD_heightmap_rain_erosion(TCOD_heightmap_t *hm, int nbDrops,float erosionCoef,float sedimentationCoef,TCOD_random_t rnd); /* TCODLIB_API void TCOD_heightmap_heat_erosion(TCOD_heightmap_t *hm, int nbPass,float minSlope,float erosionCoef,float sedimentationCoef,TCOD_random_t rnd); */ TCODLIB_API void TCOD_heightmap_kernel_transform(TCOD_heightmap_t *hm, int kernelsize, const int *dx, const int *dy, const float *weight, float minLevel,float maxLevel); TCODLIB_API void TCOD_heightmap_add_voronoi(TCOD_heightmap_t *hm, int nbPoints, int nbCoef, const float *coef,TCOD_random_t rnd); TCODLIB_API void TCOD_heightmap_mid_point_displacement(TCOD_heightmap_t *hm, TCOD_random_t rnd, float roughness); TCODLIB_API void TCOD_heightmap_add_fbm(TCOD_heightmap_t *hm, TCOD_noise_t noise,float mulx, float muly, float addx, float addy, float octaves, float delta, float scale); TCODLIB_API void TCOD_heightmap_scale_fbm(TCOD_heightmap_t *hm, TCOD_noise_t noise,float mulx, float muly, float addx, float addy, float octaves, float delta, float scale); TCODLIB_API void TCOD_heightmap_islandify(TCOD_heightmap_t *hm, float seaLevel,TCOD_random_t rnd); #ifdef __cplusplus } #endif #endif libtcod-1.6.4+dfsg/include/heightmap.hpp000066400000000000000000000623471321276576200202120ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_HEIGHTMAP_HPP #define _TCOD_HEIGHTMAP_HPP #include "heightmap.h" #include "noise.hpp" /** @PageName heightmap @PageCategory Roguelike toolkits @PageTitle Heightmap toolkit @PageDesc This toolkit allows one to create a 2D grid of float values using various algorithms. The code using the heightmap toolkit can be automatically generated with the heightmap tool (hmtool) included in the libtcod package. */ class TCODLIB_API TCODHeightMap { public : int w,h; float *values; /** @PageName heightmap_init @PageFather heightmap @PageTitle Creating a heightmap @FuncTitle Creating an empty map @FuncDesc As with other modules, you have to create a heightmap object first : Note that whereas most other modules use opaque structs, the TCOD_heightmap_t fields can be freely accessed. Thus, the TCOD_heightmap_new function returns a TCOD_heightmap_t pointer, not a TCOD_heightmap_t. The w and h fields should not be modified after the heightmap creation. The newly created heightmap is filled with 0.0 values. @Cpp TCODHeightMap::TCODHeightMap(int w, int h) @C typedef struct { int w,h; float *values; } TCOD_heightmap_t; TCOD_heightmap_t *TCOD_heightmap_new(int w,int h) @Py heightmap_new(w,h) @C# TCODHeightMap::TCODHeightMap(int w, int h) @Param w,h The width and height of the heightmap. @CppEx TCODHeightMap myMap(50,50); @CEx TCOD_heightmap_t *my_map=TCOD_heightmap_new(50,50); @PyEx map=libtcod.heightmap_new(50,50) print map.w, map.h */ TCODHeightMap(int w, int h); /** @PageName heightmap_init @FuncTitle Destroying a heightmap @FuncDesc To release the resources used by a heightmap, destroy it with : @Cpp TCODHeightMap::~TCODHeightMap() @C void TCOD_heightmap_delete(TCOD_heightmap_t *hm) @Py heightmap_delete(hm) @C# void TCODHeightMap::Dispose() @Param hm In the C version, the address of the heightmap struct returned by the creation function. */ virtual ~TCODHeightMap(); /** @PageName heightmap_base @PageFather heightmap @PageTitle Basic operations @PageDesc Those are simple operations applied either on a single map cell or on every map cell. @FuncTitle Setting a cell value @FuncDesc Once the heightmap has been created, you can do some basic operations on the values inside it. You can set a single value : @Cpp void TCODHeightMap::setValue(int x, int y, float v) @C void TCOD_heightmap_set_value(TCOD_heightmap_t *hm, int x, int y, float value) @Py heightmap_set_value(hm, x, y, value) @C# void TCODHeightMap::setValue(int x, int y, float v) @Param hm In the C version, the address of the heightmap struct returned by the creation function. @Param x,y Coordinates of the cells to modify inside the map. 0 <= x < map width 0 <= y < map height @Param value The new value of the map cell. */ inline void setValue(int x, int y, float v) { values[x+y*w]=v; } /** @PageName heightmap_base @FuncTitle Adding a float value to all cells @Cpp void TCODHeightMap::add(float value) @C void TCOD_heightmap_add(TCOD_heightmap_t *hm, float value) @Py heightmap_add(hm, value) @C# void TCODHeightMap::add(float value) @Param hm In the C version, the address of the heightmap struct returned by the creation function. @Param value Value to add to every cell. */ void add(float f); /** @PageName heightmap_base @FuncTitle Multiplying all values by a float @Cpp void TCODHeightMap::scale(float value) @C void TCOD_heightmap_scale(TCOD_heightmap_t *hm, float value) @Py heightmap_scale(hm, value) @C# void TCODHeightMap::scale(float value) @Param hm In the C version, the address of the heightmap struct returned by the creation function. @Param value Every cell's value is multiplied by this value. */ void scale(float f); /** @PageName heightmap_base @FuncTitle Resetting all values to 0.0 @Cpp void TCODHeightMap::clear() @C void TCOD_heightmap_clear(TCOD_heightmap_t *hm) @Py heightmap_clear(hm) @C# void TCODHeightMap::clear() @Param hm In the C version, the address of the heightmap struct returned by the creation function. */ void clear(); // resets all values to 0.0 /** @PageName heightmap_base @FuncTitle Clamping all values @Cpp void TCODHeightMap::clamp(float min, float max) @C void TCOD_heightmap_clamp(TCOD_heightmap_t *hm, float min, float max) @Py heightmap_clamp(hm, mi, ma) @C# void TCODHeightMap::clamp(float min, float max) @Param hm In the C version, the address of the heightmap struct returned by the creation function. @Param min,max Every cell value is clamped between min and max. min < max */ void clamp(float min, float max); /** @PageName heightmap_base @FuncTitle Copying values from another heightmap @Cpp void TCODHeightMap::copy(const TCODHeightMap *source) @C void TCOD_heightmap_copy(const TCOD_heightmap_t *source,TCOD_heightmap_t *dest) @Py heightmap_copy(source,dest) @C# void TCODHeightMap::copy(TCODHeightMap source) @Param source Each cell value from the source heightmap is copied in the destination (this for C++) heightmap. The source and destination heightmap must have the same width and height. @Param dest In the C and Python versions, the address of the destination heightmap. */ void copy(const TCODHeightMap *source); /** @PageName heightmap_base @FuncTitle Normalizing values @Cpp void TCODHeightMap::normalize(float min=0.0f, float max=1.0f) @C void TCOD_heightmap_normalize(TCOD_heightmap_t *hm, float min, float max) @Py heightmap_normalize(hm, mi=0.0, ma=1.0) @C# void TCODHeightMap::normalize() void TCODHeightMap::normalize(float min) void TCODHeightMap::normalize(float min, float max) @Param hm In the C version, the address of the heightmap struct returned by the creation function. @Param min,max The whole heightmap is translated and scaled so that the lowest cell value becomes min and the highest cell value becomes max min < max */ void normalize(float newMin=0.0f, float newMax=1.0f); // scales the values to the range [newMin;newMax] /** @PageName heightmap_base @FuncTitle Doing a lerp operation between two heightmaps @Cpp void TCODHeightMap::lerp(const TCODHeightMap *a, const TCODHeightMap *b,float coef) @C void TCOD_heightmap_lerp_hm(const TCOD_heightmap_t *a, const TCOD_heightmap_t *b, TCOD_heightmap_t *res, float coef) @Py heightmap_lerp_hm(a, b, res, coef) @C# void TCODHeightMap::lerp(TCODHeightMap a, TCODHeightMap b, float coef) @Param a First heightmap in the lerp operation. @Param b Second heightmap in the lerp operation. @Param coef lerp coefficient. For each cell in the destination map (this for C++), value = a.value + (b.value - a.value) * coef @Param res In the C and Python versions, the address of the destination heightmap. */ void lerp(const TCODHeightMap *a, const TCODHeightMap *b,float coef); /** @PageName heightmap_base @FuncTitle Adding two heightmaps @Cpp void TCODHeightMap::add(const TCODHeightMap *a, const TCODHeightMap *b) @C void TCOD_heightmap_add_hm(const TCOD_heightmap_t *a, const TCOD_heightmap_t *b, TCOD_heightmap_t *res) @Py heightmap_add_hm(a, b, res) @C# void TCODHeightMap::add(TCODHeightMap a, TCODHeightMap b) @Param a First heightmap. @Param b Second heightmap. For each cell in the destination map (this for C++), value = a.value + b.value @Param res In the C and Python versions, the address of the destination heightmap. */ void add(const TCODHeightMap *a, const TCODHeightMap *b); /** @PageName heightmap_base @FuncTitle Multiplying two heightmaps @Cpp void TCODHeightMap::multiply(const TCODHeightMap *a, const TCODHeightMap *b) @C void TCOD_heightmap_multiply_hm(const TCOD_heightmap_t *a, const TCOD_heightmap_t *b, TCOD_heightmap_t *res) @Py heightmap_multiply_hm(a, b, res) @C# void TCODHeightMap::multiply(TCODHeightMap a, TCODHeightMap b) @Param a First heightmap. @Param b Second heightmap. For each cell in the destination map (this for C++), value = a.value * b.value @Param res In the C and Python versions, the address of the destination heightmap. */ void multiply(const TCODHeightMap *a, const TCODHeightMap *b); /** @PageName heightmap_modify @PageFather heightmap @PageTitle Modifying the heightmap @PageDesc Those are advanced operations involving several or all map cells. @FuncTitle Add hills @FuncDesc This function adds a hill (a half spheroid) at given position. @Cpp void TCODHeightMap::addHill(float x, float y, float radius, float height) @C void TCOD_heightmap_add_hill(TCOD_heightmap_t *hm, float x, float y, float radius, float height) @Py heightmap_add_hill(hm, x, y, radius, height) @C# void TCODHeightMap::addHill(float x, float y, float radius, float height) @Param hm In the C version, the address of the heightmap struct returned by the creation function. @Param x,y Coordinates of the center of the hill. 0 <= x < map width 0 <= y < map height @Param radius The hill radius. @Param height The hill height. If height == radius or -radius, the hill is a half-sphere. */ void addHill(float x, float y, float radius, float height); // adds a hill (half sphere) at given position /** @PageName heightmap_modify @FuncTitle Dig hills @FuncDesc This function takes the highest value (if height > 0) or the lowest (if height < 0) between the map and the hill. It's main goal is to carve things in maps (like rivers) by digging hills along a curve. @Cpp void TCODHeightMap::digHill(float hx, float hy, float hradius, float height) @C void TCOD_heightmap_dig_hill(TCOD_heightmap_t *hm, float x, float y, float radius, float height) @Py heightmap_dig_hill(hm, x, y, radius, height) @C# void TCODHeightMap::digHill(float hx, float hy, float hradius, float height) @Param hm In the C version, the address of the heightmap struct returned by the creation function. @Param x,y Coordinates of the center of the hill. 0 <= x < map width 0 <= y < map height @Param radius The hill radius. @Param height The hill height. Can be < 0 or > 0 */ void digHill(float hx, float hy, float hradius, float height); /** @PageName heightmap_modify @FuncTitle Simulate rain erosion @FuncDesc This function simulates the effect of rain drops on the terrain, resulting in erosion patterns. @Cpp void TCODHeightMap::rainErosion(int nbDrops,float erosionCoef,float sedimentationCoef,TCODRandom *rnd) @C void TCOD_heightmap_rain_erosion(TCOD_heightmap_t *hm, int nbDrops,float erosionCoef,float sedimentationCoef,TCOD_random_t rnd) @Py heightmap_rain_erosion(hm, nbDrops,erosionCoef,sedimentationCoef,rnd=0) @C# void TCODHeightMap::rainErosion(int nbDrops, float erosionCoef, float sedimentationCoef, TCODRandom rnd) @Param hm In the C version, the address of the heightmap struct returned by the creation function. @Param nbDrops Number of rain drops to simulate. Should be at least width * height. @Param erosionCoef Amount of ground eroded on the drop's path. @Param sedimentationCoef Amount of ground deposited when the drops stops to flow @Param rnd RNG to use, NULL for default generator. */ void rainErosion(int nbDrops,float erosionCoef,float sedimentationCoef,TCODRandom *rnd); /** @PageName heightmap_modify @FuncTitle Do a generic transformation @FuncDesc This function allows you to apply a generic transformation on the map, so that each resulting cell value is the weighted sum of several neighbour cells. This can be used to smooth/sharpen the map. See examples below for a simple horizontal smoothing kernel : replace value(x,y) with 0.33*value(x-1,y) + 0.33*value(x,y) + 0.33*value(x+1,y).To do this, you need a kernel of size 3 (the sum involves 3 surrounding cells). The dx,dy array will contain : dx=-1,dy = 0 for cell x-1,y dx=1,dy=0 for cell x+1,y dx=0,dy=0 for current cell (x,y) The weight array will contain 0.33 for each cell. @Cpp void TCODHeightMap::kernelTransform(int kernelSize, int *dx, int *dy, float *weight, float minLevel,float maxLevel) @C void TCOD_heightmap_kernel_transform(TCOD_heightmap_t *hm, int kernelsize, int *dx, int *dy, float *weight, float minLevel,float maxLevel) @Py heightmap_kernel_transform(hm, kernelsize, dx, dy, weight, minLevel,maxLevel) @C# void TCODHeightMap::kernelTransform(int kernelSize, int[] dx, int[] dy, float[] weight, float minLevel, float maxLevel) @Param hm In the C version, the address of the heightmap struct returned by the creation function. kernelSize Number of neighbour cells involved. @Param dx,dy Array of kernelSize cells coordinates. The coordinates are relative to the current cell (0,0) is current cell, (-1,0) is west cell, (0,-1) is north cell, (1,0) is east cell, (0,1) is south cell, ... @Param weight Array of kernelSize cells weight. The value of each neighbour cell is scaled by its corresponding weight @Param minLevel The transformation is only applied to cells which value is >= minLevel. @Param maxLevel The transformation is only applied to cells which value is <= maxLevel. @CEx int dx [] = {-1,1,0}; int dy[] = {0,0,0}; float weight[] = {0.33f,0.33f,0.33f}; TCOD_heightMap_kernel_transform(heightmap,3,dx,dy,weight,0.0f,1.0f); @CppEx int dx [] = {-1,1,0}; int dy[] = {0,0,0}; float weight[] = {0.33f,0.33f,0.33f}; heightmap->kernelTransform(heightmap,3,dx,dy,weight,0.0f,1.0f); */ void kernelTransform(int kernelSize, const int *dx, const int *dy, const float *weight, float minLevel,float maxLevel); /** @PageName heightmap_modify @FuncTitle Add a Voronoi diagram @FuncDesc This function adds values from a Voronoi diagram to the map. @Cpp void TCODHeightMap::addVoronoi(int nbPoints, int nbCoef, float *coef,TCODRandom *rnd) @C void TCOD_heightmap_add_voronoi(TCOD_heightmap_t *hm, int nbPoints, int nbCoef, float *coef,TCOD_random_t rnd) @Py heightmap_add_voronoi(hm, nbPoints, nbCoef, coef,rnd=0) @C# void TCODHeightMap::addVoronoi(int nbPoints, int nbCoef, float[] coef, TCODRandom rnd) @Param hm In the C version, the address of the heightmap struct returned by the creation function. @Param nbPoints Number of Voronoi sites. @Param nbCoef The diagram value is calculated from the nbCoef closest sites. @Param coef The distance to each site is scaled by the corresponding coef. Closest site : coef[0], second closest site : coef[1], ... @Param rnd RNG to use, NULL for default generator. */ void addVoronoi(int nbPoints, int nbCoef, const float *coef,TCODRandom *rnd); /** @PageName heightmap_modify @FuncTitle Add a fbm This function adds values from a simplex fbm function to the map. @Cpp void TCODHeightMap::addFbm(TCODNoise *noise,float mulx, float muly, float addx, float addy, float octaves, float delta, float scale) @C void TCOD_heightmap_add_fbm(TCOD_heightmap_t *hm, TCOD_noise_t noise,float mulx, float muly, float addx, float addy, float octaves, float delta, float scale) @Py heightmap_add_fbm(hm, noise,mulx, muly, addx, addy, octaves, delta, scale) @C# void TCODHeightMap::addFbm(TCODNoise noise, float mulx, float muly, float addx, float addy, float octaves, float delta, float scale) @Param hm In the C version, the address of the heightmap struct returned by the creation function. @Param noise The 2D noise to use. @Param mulx, muly / addx, addy The noise coordinate for map cell (x,y) are (x + addx)*mulx / width , (y + addy)*muly / height. Those values allow you to scale and translate the noise function over the heightmap. @Param octaves Number of octaves in the fbm sum. @Param delta / scale The value added to the heightmap is delta + noise * scale. @Param noise is between -1.0 and 1.0 */ void addFbm(TCODNoise *noise,float mulx, float muly, float addx, float addy, float octaves, float delta, float scale); /** @PageName heightmap_modify @FuncTitle Scale with a fbm @FuncDesc This function works exactly as the previous one, but it multiplies the resulting value instead of adding it to the heightmap. @Cpp void TCODHeightMap::scaleFbm(TCODNoise *noise,float mulx, float muly, float addx, float addy, float octaves, float delta, float scale) @C void TCOD_heightmap_scale_fbm(TCOD_heightmap_t *hm, TCOD_noise_t noise,float mulx, float muly, float addx, float addy, float octaves, float delta, float scale) @Py heightmap_scale_fbm(hm, noise,mulx, muly, addx, addy, octaves, delta, scale) @C# void TCODHeightMap::scaleFbm(TCODNoise noise, float mulx, float muly, float addx, float addy, float octaves, float delta, float scale) */ void scaleFbm(TCODNoise *noise,float mulx, float muly, float addx, float addy, float octaves, float delta, float scale); /** @PageName heightmap_modify @FuncTitle Dig along a Bezier curve @FuncDesc This function carve a path along a cubic Bezier curve using the digHill function. Could be used for roads/rivers/... Both radius and depth can vary linearly along the path. @Cpp void TCODHeightMap::digBezier(int px[4], int py[4], float startRadius, float startDepth, float endRadius, float endDepth) @C void TCOD_heightmap_dig_bezier(TCOD_heightmap_t *hm, int px[4], int py[4], float startRadius, float startDepth, float endRadius, float endDepth) @Py heightmap_dig_bezier(hm, px, py, startRadius, startDepth, endRadius, endDepth) @C# void TCODHeightMap::digBezier(int[] px, int[] py, float startRadius, float startDepth, float endRadius, float endDepth) @Param hm In the C version, the address of the heightmap struct returned by the creation function. @Param px,py The coordinates of the 4 Bezier control points. @Param startRadius The path radius in map cells at point P0. Might be < 1.0 @Param startDepth The path depth at point P0. @Param endRadius The path radius in map cells at point P3. Might be < 1.0 @Param endDepth The path depth at point P3. */ void digBezier(int px[4], int py[4], float startRadius, float startDepth, float endRadius, float endDepth); /** @PageName heightmap_read @PageFather heightmap @PageTitle Reading data from the heightmap @PageDesc Those functions return raw or computed information about the heightmap. @FuncTitle Get the value of a cell @FuncDesc This function returns the height value of a map cell. @Cpp float TCODHeightMap::getValue(int x, int y) const @C float TCOD_heightmap_get_value(const TCOD_heightmap_t *hm, int x, int y) @Py heightmap_get_value(hm, x, y) @C# float TCODHeightMap::getValue(int x, int y) @Param hm In the C version, the address of the heightmap struct returned by the creation function. @Param x,y Coordinates of the map cell. 0 <= x < map width 0 <= y < map height */ inline float getValue(int x, int y) const { return values[x+y*w]; } /** @PageName heightmap_read @FuncTitle Interpolate the height @FuncDesc This function returns the interpolated height at non integer coordinates. @Cpp float TCODHeightMap::getInterpolatedValue(float x, float y) const @C float TCOD_heightmap_get_interpolated_value(const TCOD_heightmap_t *hm, float x, float y) @Py heightmap_get_interpolated_value(hm, x, y) @C# float TCODHeightMap::getInterpolatedValue(float x, float y) @Param hm In the C version, the address of the heightmap struct returned by the creation function. @Param x,y Coordinates of the map cell. 0 <= x < map width 0 <= y < map height */ float getInterpolatedValue(float x, float y) const; /** @PageName heightmap_read @FuncTitle Get the map slope @FuncDesc This function returns the slope between 0 and PI/2 at given coordinates. @Cpp float TCODHeightMap::getSlope(int x, int y) const @C float TCOD_heightmap_get_slope(const TCOD_heightmap_t *hm, int x, int y) @Py heightmap_get_slope(hm, x, y) @C# float TCODHeightMap::getSlope(int x, int y) @Param hm In the C version, the address of the heightmap struct returned by the creation function. @Param x,y Coordinates of the map cell. 0 <= x < map width 0 <= y < map height */ float getSlope(int x, int y) const; // returns the slope in radian between 0 and PI/2 /** @PageName heightmap_read @FuncTitle Get the map normal @FuncDesc This function returns the map normal at given coordinates. @Cpp void TCODHeightMap::getNormal(float x, float y,float n[3], float waterLevel=0.0f) const @C void TCOD_heightmap_get_normal(const TCOD_heightmap_t *hm, float x, float y, float n[3], float waterLevel) @Py heightmap_get_normal(hm, x, y, waterLevel) # returns nx,ny,nz @C# void TCODHeightMap::getNormal(float x, float y, float[] n, float waterLevel) @Param hm In the C version, the address of the heightmap struct returned by the creation function. @Param x,y Coordinates of the map cell. 0 <= x < map width 0 <= y < map height @Param n The function stores the normalized normal vector in this array. @Param waterLevel The map height is clamped at waterLevel so that the sea is flat. */ void getNormal(float x, float y,float n[3], float waterLevel=0.0f) const; // returns the surface normal or (0,0,1) if beyond water level. /** @PageName heightmap_read @FuncTitle Count the map cells inside a height range @FuncDesc This function returns the number of map cells which value is between min and max. @Cpp int TCODHeightMap::countCells(float min,float max) const @C int TCOD_heightmap_count_cells(const TCOD_heightmap_t *hm, float min, float max) @Py heightmap_count_cells(hm, min, max) @C# int TCODHeightMap::countCells(float min, float max) @Param hm In the C version, the address of the heightmap struct returned by the creation function. @Param min,max Only cells which value is >=min and <= max are counted. */ int countCells(float min,float max) const; /** @PageName heightmap_read @FuncTitle Check if the map is an island @FuncDesc This function checks if the cells on the map border are below a certain height. @Cpp bool TCODHeightMap::hasLandOnBorder(float waterLevel) const @C bool TCOD_heightmap_has_land_on_border(const TCOD_heightmap_t *hm, float waterLevel) @Py heightmap_has_land_on_border(hm, waterLevel) @C# bool TCODHeightMap::hasLandOnBorder(float waterLevel) @Param hm In the C version, the address of the heightmap struct returned by the creation function. @Param waterLevel Return true only if no border cell is > waterLevel. */ bool hasLandOnBorder(float waterLevel) const; /** @PageName heightmap_read @FuncTitle Get the map min and max values @FuncDesc This function calculates the min and max of all values inside the map. @Cpp void TCODHeightMap::getMinMax(float *min, float *max) const @C void TCOD_heightmap_get_minmax(const TCOD_heightmap_t *hm, float *min, float *max) @Py heightmap_get_minmax(hm) # returns min,max @C# void TCODHeightMap::getMinMax(out float min, out float max) @Param hm In the C version, the address of the heightmap struct returned by the creation function. @Param min, max The min and max values are returned in these variables. */ void getMinMax(float *min, float *max) const; // void heatErosion(int nbPass,float minSlope,float erosionCoef,float sedimentationCoef,TCODRandom *rnd); /** @PageName heightmap_modify @FuncTitle Generate a map with mid-point displacement @FuncDesc This algorithm generates a realistic fractal heightmap using the diamond-square (or random midpoint displacement) algorithm. The roughness range should be comprised between 0.4 and 0.6. The image below show the same map with roughness varying from 0.4 to 0.6. It's also a good habit to normalize the map after using this algorithm to avoid unexpected heights. @Cpp void TCODHeightMap::midPointDisplacement(TCODRandom *rng=NULL,float roughness=0.45f) @C void TCOD_heightmap_mid_point_displacement(TCOD_heightmap_t *hm, TCOD_random_t rnd, float roughness) @Py heightmap_mid_point_displacement(hm, rng, roughness) @Param hm In the C and Python version, the address of the heightmap struct returned by the creation function. @Param rng Random number generation to use, or NULL/0 to use the default one. @Param roughness Map roughness. */ void midPointDisplacement(TCODRandom *rnd = NULL, float roughness=0.45f); void islandify(float seaLevel,TCODRandom *rnd); // lowers the terrain near the heightmap borders // TODO : checks island connectivity with floodfill private : // void setMPDHeight(TCODRandom *rnd,int x,int y, float z, float offset); // void setMDPHeightSquare(TCODRandom *rnd,int x, int y, int initsz, int sz,float offset); }; #endif libtcod-1.6.4+dfsg/include/howto.hpp000066400000000000000000000132771321276576200174020ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* This file contains no code. It's only an input for doctcod */ /** @PageName compile_libtcod @PageCategory Howtos @PageTitle How to compile libtcod @PageDesc This page contains howtos about how to get the latest libtcod source code and compile it. */ /** @PageName compile_libtcod_mingw @PageFather compile_libtcod @PageTitle On Windows with Mingw @PageDesc

Mingw installation

Download the latest version of Mingw from this address : http://sourceforge.net/projects/mingw/files/ The latest installer should be at the top of the page with a name starting with mingw-get-inst.. Download and run the program. Follow the installation steps. Be sure to check the "Use pre-packaged repository" option : The latest version might be less stable and might not work with a precompiled libtcod. When you arrive at the component selection screen, check C compiler, C++ compiler and MSys system : Keep on following the installation steps until the installation is finished. Now you have a "Mingw Shell" program in your start menu. This is the terminal you will use to compile and debug your game.

TortoiseHg installation

In order to get the latest version of libtcod, you need a mercurial client. Go to the download page and grab the client corresponding to your version of Windows : http://tortoisehg.bitbucket.org/download/index.html Follow the installation wizard using the default configuration. Once the installation is finished, restart your computer. Now you should be able to use mercurial (hg) from the Mingw Shell. To check if everything is ok, start a shell and type "which hg" :

Getting libtcod source code

In Mingw Shell, type :
hg clone https://bitbucket.org/jice/libtcod
This might take some time so grab a beer. Once it's finished, a libtcod directory has been created. You can check the documentation (the same you're currently reading) in libtcod/doc/index2.html. The headers are in libtcod/include. The source code in libtcod/src.

Compiling libtcod

Go in libtcod's main directory :
cd libtcod
And start the compilation :
make -f makefiles/makefile-mingw
The compilation make take a few seconds depending on your CPU speed. Once it's finished, compile the samples :
make -f makefiles/makefile-samples-mingw
Check that everything is ok by running the samples :
./samples_cpp
*/ /** @PageName compile_libtcod_linux @PageFather compile_libtcod @PageTitle On Linux @PageDesc

Linux compilation

On a freshly installed Ubuntu : Get the tools :
sudo apt-get install gcc g++ make upx electric-fence libsdl1.2-dev mercurial
Get the latest sources :
hg clone https://bitbucket.org/jice/libtcod
Compile the library :
cd libtcod/
make -f makefiles/makefile-linux clean all
Compile the samples :
make -f makefiles/makefile-samples-linux
Enjoy :
./samples_cpp
*/ /** @PageName compile_libtcod_codelite @PageFather compile_libtcod @PageTitle Using CodeLite @PageDesc TODO */ /** @PageName compile_libtcod_haiku @PageFather compile_libtcod @PageTitle On Haiku @PageDesc TODO */ /** @PageName start_project @PageCategory Howtos @PageTitle How to start a project @PageDesc This page contains howtos about how to create a project from scratch */ /** @PageName start_mingw @PageFather start_project @PageTitle On Windows with Mingw @PageDesc TODO */ /** @PageName start_linux @PageFather start_project @PageTitle On Linux @PageDesc TODO */ /** @PageName start_codelite @PageFather start_project @PageTitle Using CodeLite @PageDesc TODO */ libtcod-1.6.4+dfsg/include/image.h000066400000000000000000000072331321276576200167570ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_IMAGE_H #define _TCOD_IMAGE_H #include "color.h" #ifdef TCOD_IMAGE_SUPPORT #include "console_types.h" #ifdef __cplusplus extern "C" { #endif typedef void *TCOD_image_t; TCODLIB_API TCOD_image_t TCOD_image_new(int width, int height); #ifdef TCOD_CONSOLE_SUPPORT TCODLIB_API TCOD_image_t TCOD_image_from_console(TCOD_console_t console); TCODLIB_API void TCOD_image_refresh_console(TCOD_image_t image, TCOD_console_t console); #endif TCODLIB_API TCOD_image_t TCOD_image_load(const char *filename); TCODLIB_API void TCOD_image_clear(TCOD_image_t image, TCOD_color_t color); TCODLIB_API void TCOD_image_invert(TCOD_image_t image); TCODLIB_API void TCOD_image_hflip(TCOD_image_t image); TCODLIB_API void TCOD_image_rotate90(TCOD_image_t image, int numRotations); TCODLIB_API void TCOD_image_vflip(TCOD_image_t image); TCODLIB_API void TCOD_image_scale(TCOD_image_t image, int neww, int newh); TCODLIB_API void TCOD_image_save(TCOD_image_t image, const char *filename); TCODLIB_API void TCOD_image_get_size(TCOD_image_t image, int *w,int *h); TCODLIB_API TCOD_color_t TCOD_image_get_pixel(TCOD_image_t image,int x, int y); TCODLIB_API int TCOD_image_get_alpha(TCOD_image_t image,int x, int y); TCODLIB_API TCOD_color_t TCOD_image_get_mipmap_pixel(TCOD_image_t image,float x0,float y0, float x1, float y1); TCODLIB_API void TCOD_image_put_pixel(TCOD_image_t image,int x, int y,TCOD_color_t col); #ifdef TCOD_CONSOLE_SUPPORT TCODLIB_API void TCOD_image_blit(TCOD_image_t image, TCOD_console_t console, float x, float y, TCOD_bkgnd_flag_t bkgnd_flag, float scalex, float scaley, float angle); TCODLIB_API void TCOD_image_blit_rect(TCOD_image_t image, TCOD_console_t console, int x, int y, int w, int h, TCOD_bkgnd_flag_t bkgnd_flag); TCODLIB_API void TCOD_image_blit_2x(TCOD_image_t image, TCOD_console_t dest, int dx, int dy, int sx, int sy, int w, int h); #endif TCODLIB_API void TCOD_image_delete(TCOD_image_t image); TCODLIB_API void TCOD_image_set_key_color(TCOD_image_t image, TCOD_color_t key_color); TCODLIB_API bool TCOD_image_is_pixel_transparent(TCOD_image_t image, int x, int y); #ifdef __cplusplus } #endif #endif /* TCOD_IMAGE_SUPPORT */ #endif /* _TCOD_IMAGE_H */ libtcod-1.6.4+dfsg/include/image.hpp000066400000000000000000000502231321276576200173140ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_IMAGE_HPP #define _TCOD_IMAGE_HPP #include "color.hpp" #ifdef TCOD_IMAGE_SUPPORT #ifdef TCOD_CONSOLE_SUPPORT #include "console.hpp" #endif #include "image.h" #ifdef TCOD_CONSOLE_SUPPORT class TCODConsole; #endif class TCODLIB_API TCODImage { public : /** @PageName image @PageTitle Image toolkit @PageCategory Base toolkits @PageDesc This toolkit contains some image manipulation utilities. */ /** @PageName image_create @PageTitle Creating an image @PageFather image @FuncTitle Creating an empty image @FuncDesc You can create an image of any size, filled with black with this function. @Cpp TCODImage::TCODImage(int width, int height) @C TCOD_image_t TCOD_image_new(int width, int height) @Py image_new( width, height) @C# TCODImage::TCODImage(int width, int height) @Param width,height Size of the image in pixels. @CppEx TCODImage *pix = new TCODImage(80,50); @CEx TCOD_image_t pix = TCOD_image_new(80,50); @PyEx pix = litbcod.image_new(80,50) */ TCODImage(int width, int height); /** @PageName image_create @FuncTitle Loading a .bmp or .png image @FuncDesc You can read data from a .bmp or .png file (for example to draw an image using the background color of the console cells). Note that only 24bits and 32bits PNG files are currently supported. @Cpp TCODImage::TCODImage(const char *filename) @C TCOD_image_t TCOD_image_load(const char *filename) @Py image_load(filename) @C# TCODImage::TCODImage(string filename) @Param filename Name of the .bmp or .png file to load. @CppEx TCODImage *pix = new TCODImage("mypic.bmp"); @CEx TCOD_image_t pix = TCOD_image_load("mypic.bmp"); @PyEx pix = libtcod.image_load("mypic.bmp") */ TCODImage(const char *filename); #ifdef TCOD_CONSOLE_SUPPORT /** @PageName image_create @FuncTitle Creating an image from a console @FuncDesc You can create an image from any console (either the root console or an offscreen console). The image size will depend on the console size and the font characters size. You can then save the image to a file with the save function. @Cpp TCODImage::TCODImage(const TCODConsole *console) @C TCOD_image_t TCOD_image_from_console(TCOD_console_t console) @Py image_from_console(console) @C# TCODImage::TCODImage(TCODConsole console) @Param console The console to convert. In the C version, use NULL for the root console. @CppEx TCODImage *pix = new TCODImage(TCODConsole::root); @CEx TCOD_image_t pix = TCOD_image_from_console(NULL); @PyEx pix = libtcod.image_from_console(0) */ TCODImage(const TCODConsole *console); /** @PageName image_create @FuncTitle refreshing an image created from a console @FuncDesc If you need to refresh the image with the console's new content, you don't have to delete it and create another one. Instead, use this function. Note that you must use the same console that was used in the TCOD_image_from_console call (or at least a console with the same size). @Cpp void TCODImage::refreshConsole(const TCODConsole *console) @C void TCOD_image_refresh_console(TCOD_image_t image, TCOD_console_t console) @Py image_refresh_console(image, console) @C# void TCODImage::refreshConsole(TCODConsole console) @Param image In the C version, the image created with TCOD_image_from_console. @Param console The console to capture. In the C version, use NULL for the root console. @CppEx TCODImage *pix = new TCODImage(TCODConsole::root); // create an image from the root console // ... modify the console pix->refreshConsole(TCODConsole::root); // update the image with the console's new content @CEx TCOD_image_t pix = TCOD_image_from_console(NULL); // ... modify the console .. TCOD_image_refresh_console(pix,NULL); @PyEx pix = libtcod.image_from_console(0) # ... modify the console .. libtcod.image_refresh_console(pix,0) */ void refreshConsole(const TCODConsole *console); #endif /** @PageName image_read @PageTitle Reading data from a TCODImage @PageFather image @FuncTitle Getting the size of an image @FuncDesc You can read the size of an image in pixels with this function. @Cpp void TCODImage::getSize(int *w,int *h) const @C void TCOD_image_get_size(TCOD_image_t image, int *w,int *h) @Py image_get_size(image) # returns w,h @C# void TCODImage::getSize(out int w, out int h) @Param image In the C version, the image handler, obtained with the load function. @Param w,h When the function returns, those variables contain the size of the image. @CppEx TCODImage *pix = new TCODImage(80,50); int w,h; pix->getSize(&w,&h); // w = 80, h = 50 @CEx TCOD_image_t pix = TCOD_image_new(80,50); int w,h; TCOD_image_get_size(pix,&w,&h); // w = 80, h = 50 @PyEx pix = libtcod.image_new(80,50) w,h=libtcod.image_get_size(pix) # w = 80, h = 50 */ void getSize(int *w,int *h) const; /** @PageName image_read @FuncTitle Getting the color of a pixel @FuncDesc You can read the colors from an image with this function. @Cpp TCODColor TCODImage::getPixel(int x, int y) const @C TCOD_color_t TCOD_image_get_pixel(TCOD_image_t image,int x, int y) @Py image_get_pixel(image, x, y) @C# TCODColor TCODImage::getPixel(int x, int y) @Param image In the C and Python version, the image handler, obtained with the load function. @Param x,y The pixel coordinates inside the image. 0 <= x < width 0 <= y < height @CppEx TCODImage *pix = new TCODImage(80,50); TCODColor col=pix->getPixel(40,25); @CEx TCOD_image_t pix = TCOD_image_new(80,50); TCOD_color_t col=TCOD_image_get_pixel(pix,40,25); @PyEx pix = litbcod.image_new(80,50) col=litbcod.image_get_pixel(pix,40,25) */ TCODColor getPixel(int x, int y) const; /** @PageName image_read @FuncTitle Getting the alpha value of a pixel @FuncDesc If you have set a key color for this image with setKeyColor, or if this image was created from a 32 bits PNG file (with alpha layer), you can get the pixel transparency with this function. This function returns a value between 0 (transparent pixel) and 255 (opaque pixel). @Cpp int TCODImage::getAlpha(int x, int y) const @C int TCOD_image_get_alpha(TCOD_image_t image, int x, int y) @Py image_get_alpha(image, x, y) @C# int TCODImage::getAlpha(int x, int y) @Param image In the C and Python version, the image handler, obtained with the load function. @Param x,y The pixel coordinates inside the image. 0 <= x < width 0 <= y < height */ int getAlpha(int x,int y) const; /** @PageName image_read @FuncTitle Checking if a pixel is transparent @FuncDesc You can use this simpler version (for images with alpha layer, returns true only if alpha == 0) : @Cpp bool TCODImage::isPixelTransparent(int x,int y) const @C bool TCOD_image_is_pixel_transparent(TCOD_image_t image,int x, int y) @Py image_is_pixel_transparent(image, x, y) @C# bool TCODImage::isPixelTransparent(int x,int y) @Param image In the C and Python version, the image handler, obtained with the load function. @Param x,y The pixel coordinates inside the image. 0 <= x < width 0 <= y < height */ bool isPixelTransparent(int x, int y) const; /** @PageName image_read @FuncTitle Getting the average color of a part of the image @FuncDesc This method uses mipmaps to get the average color of an arbitrary rectangular region of the image. It can be used to draw a scaled-down version of the image. It's used by libtcod's blitting functions. @Cpp TCODColor TCODImage::getMipmapPixel(float x0,float y0, float x1, float y1) @C TCOD_color_t TCOD_image_get_mipmap_pixel(TCOD_image_t image,float x0,float y0, float x1, float y1) @Py image_get_mipmap_pixel(image,x0,y0, x1, y1) @C# TCODColor TCODImage::getMipmapPixel(float x0,float y0, float x1, float y1) @Param image In the C version, the image handler, obtained with the load function. @Param x0,y0 Coordinates in pixels of the upper-left corner of the region. 0.0 <= x0 < x1 0.0 <= y0 < y1 @Param x1,y1 Coordinates in pixels of the lower-right corner of the region. x0 < x1 < width y0 < y1 < height @CppEx // Get the average color of a 5x5 "superpixel" in the center of the image. TCODImage *pix = new TCODImage(80,50); TCODColor col=pix->getMipMapPixel(37.5f, 22.5f, 42.5f, 28.5f); @CEx TCOD_image_t pix = TCOD_image_new(80,50); TCOD_color_t col=TCOD_image_get_mipmap_pixel(pix,37.5f, 22.5f, 42.5f, 28.5f); @PyEx pix = libtcod.image_new(80,50) col=libtcod.image_get_mipmap_pixel(pix,37.5, 22.5, 42.5, 28.5) */ TCODColor getMipmapPixel(float x0,float y0, float x1, float y1); /** @PageName image_update @PageTitle Updating an image @PageFather image @FuncTitle Filling an image with a color @FuncDesc You can fill the whole image with a color with : @Cpp void TCODImage::clear(const TCODColor color) @C void TCOD_image_clear(TCOD_image_t image, TCOD_color_t color) @Py image_clear(image,color) @C# void TCODImage::clear(TCODColor color) @Param image In the C and Python version, the image to fill. @Param color The color to use. */ void clear(const TCODColor col); /** @PageName image_update @FuncTitle Changing the color of a pixel @Cpp TCODColor TCODImage::putPixel(int x, int y, const TCODColor col) @C void TCOD_image_put_pixel(TCOD_image_t image,int x, int y,TCOD_color_t col) @Py image_put_pixel(image,x, y,col) @C# TCODColor TCODImage::putPixel(int x, int y, TCODColor col) @Param image In the C version, the image handler, obtained with the load function. @Param x,y The pixel coordinates inside the image. 0 <= x < width 0 <= y < height @Param col The new color of the pixel. */ void putPixel(int x, int y, const TCODColor col); /** @PageName image_update @FuncTitle Scaling an image @FuncDesc You can resize an image and scale its content. If neww < oldw or newh < oldh, supersampling is used to scale down the image. Else the image is scaled up using nearest neightbor. @Cpp void TCODImage::scale(int neww, int newh) @C void TCOD_image_scale(TCOD_image_t image,int neww, int newh) @Py image_scale(image, neww,newh) @C# void TCODImage::scale(int neww, int newh) @Param image In the C and Python version, the image handler, obtained with the load function. @Param neww,newh The new size of the image. */ void scale(int neww, int newh); /** @PageName image_update @FuncTitle Flipping the image horizontally @Cpp void TCODImage::hflip() @C void TCOD_image_hflip(TCOD_image_t image) @Py image_hflip(image) @C# void TCODImage::hflip() @Param image In the C and Python version, the image handler, obtained with the load function. */ void hflip(); /** @PageName image_update @FuncTitle Flipping the image vertically @Cpp void TCODImage::vflip() @C void TCOD_image_vflip(TCOD_image_t image) @Py image_vflip(image) @C# void TCODImage::vflip() @Param image In the C and Python version, the image handler, obtained with the load function. */ void vflip(); /** @PageName image_update @FuncTitle Rotating the image clockwise @FuncDesc Rotate the image clockwise by increment of 90 degrees. @Cpp void TCODImage::rotate90(int numRotations=1) @C void TCOD_image_rotate90(TCOD_image_t image, int numRotations) @Py image_rotate90(image, num=1) @C# void TCODImage::rotate90(int numRotations) @Param image In the C and Python version, the image handler, obtained with the load function. @Param numRotations Number of 90 degrees rotations. Should be between 1 and 3. */ void rotate90(int numRotations=1); /** @PageName image_update @FuncTitle Inverting the colors of the image @Cpp void TCODImage::invert() @C void TCOD_image_invert(TCOD_image_t image) @Py image_invert(image) @C# void TCODImage::invert() @Param image In the C and Python version, the image handler, obtained with the load function. */ void invert(); /** @PageName image_save @PageFather image @PageTitle Saving an image to a bmp or png file. @PageDesc You can save an image to a 24 bits .bmp or .png file. @Cpp void TCODImage::save(const char *filename) @C void TCOD_image_save(TCOD_image_t image, const char *filename) @Py image_save(image, filename) @C# void TCODImage::save(string filename) @Param image In the C version, the image handler, obtained with any image creation function. @Param filename Name of the .bmp or .png file. @CppEx TCODImage *pix = new TCODImage(10,10); pix->save("mypic.bmp"); @CEx TCOD_image_t pix = TCOD_image_from_console(my_offscreen_console); TCOD_image_save(pix,"mypic.bmp"); @PyEx pix = libtcod.image_from_console(my_offscreen_console) libtcod.image_save(pix,"mypic.bmp") */ void save(const char *filename) const; #ifdef TCOD_CONSOLE_SUPPORT /** @PageName image_blit @PageFather image @PageTitle Blitting an image on a console @FuncTitle Standard blitting @FuncDesc This function blits a rectangular part of the image on a console without scaling it or rotating it. Each pixel of the image fills a console cell. @Cpp void TCODImage::blitRect(TCODConsole *console, int x, int y, int w=-1, int h=-1, TCOD_bkgnd_flag_t bkgnd_flag = TCOD_BKGND_SET ) const @C void TCOD_image_blit_rect(TCOD_image_t image, TCOD_console_t console, int x, int y, int w, int h, TCOD_bkgnd_flag_t bkgnd_flag) @Py image_blit_rect(image, console, x, y, w, h, bkgnd_flag) @C# void TCODImage::blitRect(TCODConsole console, int x, int y) void TCODImage::blitRect(TCODConsole console, int x, int y, int w) void TCODImage::blitRect(TCODConsole console, int x, int y, int w, int h) void TCODImage::blitRect(TCODConsole console, int x, int y, int w, int h, TCODBackgroundFlag bkgnd_flag) @Param image In the C version, the image handler, obtained with the load function. @Param console The console on which the image will be drawn. In the C version, use NULL for the root console. @Param x,y Coordinates in the console of the upper-left corner of the image. @Param w,h Dimension of the image on the console. Use -1,-1 to use the image size. @Param flag This flag defines how the cell's background color is modified. See TCOD_bkgnd_flag_t. */ void blitRect(TCODConsole *console, int x, int y, int w=-1, int h=-1, TCOD_bkgnd_flag_t bkgnd_flag = TCOD_BKGND_SET ) const; /** @PageName image_blit @FuncTitle Blitting with scaling and/or rotation @FuncDesc This function allows you to specify the floating point coordinates of the center of the image, its scale and its rotation angle. @Cpp void TCODImage::blit(TCODConsole *console, float x, float y, TCOD_bkgnd_flag_t bkgnd_flag = TCOD_BKGND_SET, float scalex=1.0f, float scaley=1.0f, float angle=0.0f) const @C void TCOD_image_blit(TCOD_image_t image, TCOD_console_t console, int x, int y, TCOD_bkgnd_flag_t bkgnd_flag, float scalex, float scaley, float angle) @Py image_blit(image, console, x, y, bkgnd_flag, scalex, scaley, angle) @C# void TCODImage::blit(TCODConsole console, float x, float y) void TCODImage::blit(TCODConsole console, float x, float y, TCODBackgroundFlag bkgnd_flag) void TCODImage::blit(TCODConsole console, float x, float y, TCODBackgroundFlag bkgnd_flag, float scalex) void TCODImage::blit(TCODConsole console, float x, float y, TCODBackgroundFlag bkgnd_flag, float scalex, float scaley) void TCODImage::blit(TCODConsole console, float x, float y, TCODBackgroundFlag bkgnd_flag, float scalex, float scaley, float angle) @Param image In the C version, the image handler, obtained with the load function. @Param console The console on which the image will be drawn. In the C version, use NULL for the root console. @Param x,y Coordinates in the console of the center of the image. @Param flag This flag defines how the cell's background color is modified. See TCOD_bkgnd_flag_t. @Param scalex,scaley Scale coefficient. Must be > 0.0. @Param angle Rotation angle in radians. */ void blit(TCODConsole *console, float x, float y, TCOD_bkgnd_flag_t bkgnd_flag = TCOD_BKGND_SET, float scalex=1.0f, float scaley=1.0f, float angle=0.0f) const; #endif /** @PageName image_blit @FuncTitle Blitting with a mask @FuncDesc When blitting an image, you can define a key color that will be ignored by the blitting function. This makes it possible to blit non rectangular images or images with transparent pixels. @Cpp void TCODImage::setKeyColor(const TCODColor keyColor) @C void TCOD_image_set_key_color(TCOD_image_t image, TCOD_color_t keyColor) @Py image_set_key_color(image, keyColor) @C# void TCODImage::setKeyColor(TCODColor keyColor) @Param image In the C and Python version, the image handler, obtained with the load function. @Param color Pixels with this color will be skipped by blitting functions. @CppEx TCODImage *pix = TCODImage("mypix.bmp"); pix->setKeyColor(TCODColor::red); // blitting the image, omitting red pixels pix->blitRect(TCODConsole::root,40,25); @CEx TCOD_image_t pix = TCOD_image_new(10,10); TCOD_image_set_key_color(pix,TCOD_red); TCOD_image_blit_rect(pix,NULL,40,25,5,5,TCOD_BKGND_SET); @PyEx pix = libtcod.image_new(10,10) libtcod.image_set_key_color(pix,libtcod.red) libtcod.image_blit_rect(pix,0,40,25,5,5,libtcod.BKGND_SET) */ void setKeyColor(const TCODColor keyColor); #ifdef TCOD_CONSOLE_SUPPORT /** @PageName image_blit @FuncTitle Blitting with subcell resolution @FuncDesc Eventually, you can use some special characters in the libtcod fonts : to double the console resolution using this blitting function.
Comparison before/after subcell resolution in TCOD :
Pyromancer ! screenshot, making full usage of subcell resolution :
@Cpp void TCODImage::blit2x(TCODConsole *dest, int dx, int dy, int sx=0, int sy=0, int w=-1, int h=-1 ) const; @C void TCOD_image_blit_2x(TCOD_image_t image, TCOD_console_t dest, int dx, int dy, int sx, int sy, int w, int h); @Py image_blit_2x(image, dest, dx, dy, sx=0, sy=0, w=-1, h=-1) @C# void TCODImage::blit2x(TCODConsole dest, int dx, int dy); void TCODImage::blit2x(TCODConsole dest, int dx, int dy, int sx); void TCODImage::blit2x(TCODConsole dest, int dx, int dy, int sx, int sy); void TCODImage::blit2x(TCODConsole dest, int dx, int dy, int sx, int sy, int w); void TCODImage::blit2x(TCODConsole dest, int dx, int dy, int sx, int sy, int w, int h); @Param image In the C and Python version, the image handler, obtained with the load function. @Param dest The console of which the image will be blited. Foreground, background and character data will be overwritten. @Param dx,dy Coordinate of the console cell where the upper left corner of the blitted image will be. @Param sx,sy,w,h Part of the image to blit. Use -1 in w and h to blit the whole image. */ void blit2x(TCODConsole *dest, int dx, int dy, int sx=0, int sy=0, int w=-1, int h=-1) const; #endif TCODImage(TCOD_image_t img) : data(img), deleteData(false) {} virtual ~TCODImage(); protected : friend class TCODLIB_API TCODSystem; friend class TCODLIB_API TCODZip; void *data; bool deleteData; }; #endif /* TCOD_IMAGE_SUPPORT */ #endif /* _TCOD_IMAGE_HPP */ libtcod-1.6.4+dfsg/include/lex.h000066400000000000000000000101101321276576200164510ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This is a libtcod internal module. * Use at your own risks... */ #ifndef _TCOD_LEX_H #define _TCOD_LEX_H #include "libtcod_portability.h" #ifdef __cplusplus extern "C" { #endif #define TCOD_LEX_FLAG_NOCASE 1 #define TCOD_LEX_FLAG_NESTING_COMMENT 2 #define TCOD_LEX_FLAG_TOKENIZE_COMMENTS 4 #define TCOD_LEX_ERROR -1 #define TCOD_LEX_UNKNOWN 0 #define TCOD_LEX_SYMBOL 1 #define TCOD_LEX_KEYWORD 2 #define TCOD_LEX_IDEN 3 #define TCOD_LEX_STRING 4 #define TCOD_LEX_INTEGER 5 #define TCOD_LEX_FLOAT 6 #define TCOD_LEX_CHAR 7 #define TCOD_LEX_EOF 8 #define TCOD_LEX_COMMENT 9 #define TCOD_LEX_MAX_SYMBOLS 100 #define TCOD_LEX_SYMBOL_SIZE 5 #define TCOD_LEX_MAX_KEYWORDS 100 #define TCOD_LEX_KEYWORD_SIZE 20 typedef struct { int file_line, token_type, token_int_val, token_idx; float token_float_val; char *tok; int toklen; char lastStringDelim; char *pos; char *buf; char *filename; char *last_javadoc_comment; /* private stuff */ int nb_symbols, nb_keywords, flags; char symbols[ TCOD_LEX_MAX_SYMBOLS][ TCOD_LEX_SYMBOL_SIZE ], keywords[ TCOD_LEX_MAX_KEYWORDS ][ TCOD_LEX_KEYWORD_SIZE ]; const char *simpleCmt; const char *cmtStart, *cmtStop, *javadocCmtStart; const char *stringDelim; bool javadoc_read; bool allocBuf; bool savept; /* is this object a savepoint (no free in destructor) */ } TCOD_lex_t; TCODLIB_API TCOD_lex_t *TCOD_lex_new_intern(void); TCODLIB_API TCOD_lex_t *TCOD_lex_new(const char **symbols, const char **keywords, const char *simpleComment, const char *commentStart, const char *commentStop, const char *javadocCommentStart, const char *stringDelim, int flags); TCODLIB_API void TCOD_lex_delete(TCOD_lex_t *lex); TCODLIB_API void TCOD_lex_set_data_buffer(TCOD_lex_t *lex,char *dat); TCODLIB_API bool TCOD_lex_set_data_file(TCOD_lex_t *lex,const char *filename); TCODLIB_API int TCOD_lex_parse(TCOD_lex_t *lex); TCODLIB_API int TCOD_lex_parse_until_token_type(TCOD_lex_t *lex,int token_type); TCODLIB_API int TCOD_lex_parse_until_token_value(TCOD_lex_t *lex,const char *token_value); TCODLIB_API bool TCOD_lex_expect_token_type(TCOD_lex_t *lex,int token_type); TCODLIB_API bool TCOD_lex_expect_token_value(TCOD_lex_t *lex,int token_type,const char *token_value); TCODLIB_API void TCOD_lex_savepoint(TCOD_lex_t *lex,TCOD_lex_t *savept); TCODLIB_API void TCOD_lex_restore(TCOD_lex_t *lex,TCOD_lex_t *savept); TCODLIB_API char *TCOD_lex_get_last_javadoc(TCOD_lex_t *lex); TCODLIB_API const char *TCOD_lex_get_token_name(int token_type); TCODLIB_API char *TCOD_lex_get_last_error(void); TCODLIB_API int TCOD_lex_hextoint(char c); #ifdef __cplusplus } #endif #endif libtcod-1.6.4+dfsg/include/lex.hpp000066400000000000000000000062141321276576200170230ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This is a libtcod internal module. * Use at your own risks... */ #ifndef _TCOD_LEX_HPP #define _TCOD_LEX_HPP #include "lex.h" class TCODLIB_API TCODLex { public : TCODLex(); TCODLex( const char **symbols, const char **keywords, const char *simpleComment="//", const char *commentStart="/*", const char *commentStop="*/", const char *javadocCommentStart="/**", const char *stringDelim="\"", int flags=TCOD_LEX_FLAG_NESTING_COMMENT); ~TCODLex(); void setDataBuffer(char *dat); bool setDataFile(const char *filename); int parse(void); int parseUntil(int tokenType); int parseUntil(const char *tokenValue); bool expect(int tokenType); bool expect(int tokenType,const char *tokenValue); void savepoint(TCODLex *savept); void restore(TCODLex *savept); char *getLastJavadoc(); int getFileLine() { return ((TCOD_lex_t *)data)->file_line; } int getTokenType() { return ((TCOD_lex_t *)data)->token_type; } int getTokenIntVal() { return ((TCOD_lex_t *)data)->token_int_val; } int getTokenIdx() { return ((TCOD_lex_t *)data)->token_idx; } float getTokenFloatVal() { return ((TCOD_lex_t *)data)->token_float_val; } char *getToken() { return ((TCOD_lex_t *)data)->tok; } char getStringLastDelimiter() { return ((TCOD_lex_t *)data)->lastStringDelim; } char *getPos() { return ((TCOD_lex_t *)data)->pos; } char *getBuf() { return ((TCOD_lex_t *)data)->buf; } char *getFilename() { return ((TCOD_lex_t *)data)->filename; } char *getLastJavadocComment() { return ((TCOD_lex_t *)data)->last_javadoc_comment; } static const char *getTokenName(int tokenType) { return TCOD_lex_get_token_name(tokenType); } protected : void *data; }; #endif libtcod-1.6.4+dfsg/include/libtcod.h000066400000000000000000000040031321276576200173050ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _LIBTCOD_H #define _LIBTCOD_H #include "libtcod_portability.h" #include "libtcod_utility.h" #include "libtcod_version.h" #include "bresenham.h" #include "bsp.h" #include "color.h" #include "console.h" #include "fov.h" #include "heightmap.h" #include "image.h" #include "lex.h" #include "list.h" #include "mersenne.h" #include "mouse.h" #include "namegen.h" #include "noise.h" #include "path.h" #include "parser.h" #include "sys.h" #include "tree.h" #include "txtfield.h" #include "zip.h" #endif libtcod-1.6.4+dfsg/include/libtcod.hpp000066400000000000000000000037471321276576200176630ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _LIBTCOD_HPP #define _LIBTCOD_HPP #include "libtcod.h" #include "bresenham.hpp" #include "bsp.hpp" #include "color.hpp" #include "console.hpp" #include "fov.hpp" #include "heightmap.hpp" #include "image.hpp" #include "lex.hpp" #include "list.hpp" #include "mersenne.hpp" #include "mouse.hpp" #include "namegen.hpp" #include "noise.hpp" #include "parser.hpp" #include "path.hpp" #include "sys.hpp" #include "tree.hpp" #include "txtfield.hpp" #include "zip.hpp" #endif libtcod-1.6.4+dfsg/include/libtcod_int.h000066400000000000000000000450241321276576200201670ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCODLIB_INT_H #define _TCODLIB_INT_H #include #include #if defined(__ANDROID__) #include #endif #ifdef TCOD_SDL2 #include #endif #include "libtcod_portability.h" #include "color.h" #include "console_types.h" #include "fov.h" #include "fov_types.h" #include "mersenne_types.h" #include "sys.h" /* tcodlib internal stuff */ #ifdef __cplusplus extern "C" { #endif #ifdef TCOD_CONSOLE_SUPPORT typedef struct { int *ch_array; /* character code array */ TCOD_image_t fg_colors, bg_colors; /* console width and height (in characters,not pixels) */ int w,h; /* default background operator for print & print_rect functions */ TCOD_bkgnd_flag_t bkgnd_flag; /* default alignment for print & print_rect functions */ TCOD_alignment_t alignment; /* foreground (text), background colors */ TCOD_color_t fore, back; } TCOD_console_data_t; #endif /* fov internal stuff */ typedef struct { bool transparent:1; bool walkable:1; bool fov:1; } cell_t; typedef struct { int width; int height; int nbcells; cell_t *cells; } map_t; /* pseudorandom number generator toolkit */ typedef struct { /* algorithm identifier */ TCOD_random_algo_t algo; /* distribution */ TCOD_distribution_t distribution; /* Mersenne Twister stuff */ uint32_t mt[624]; int cur_mt; /* Complementary-Multiply-With-Carry stuff */ /* shared with Generalised Feedback Shift Register */ uint32_t Q[4096], c; int cur; } mersenne_data_t; typedef struct { /* number of characters in the bitmap font */ int fontNbCharHoriz; int fontNbCharVertic; /* font type and layout */ bool font_tcod_layout; bool font_in_row; bool font_greyscale; /* character size in font */ int font_width; int font_height; char font_file[512]; char window_title[512]; /* ascii code to tcod layout converter */ int *ascii_to_tcod; /* whether each character in the font is a colored tile */ bool *colored; #ifdef TCOD_CONSOLE_SUPPORT /* the root console */ TCOD_console_data_t *root; /* nb chars in the font */ int max_font_chars; /* fullscreen data */ bool fullscreen; int fullscreen_offsetx; int fullscreen_offsety; /* asked by the user */ int fullscreen_width; int fullscreen_height; /* actual resolution */ int actual_fullscreen_width; int actual_fullscreen_height; #endif #ifdef TCOD_SDL2 /* renderer to use */ TCOD_renderer_t renderer; /* user post-processing callback */ SDL_renderer_t sdl_cbk; #endif /* fading data */ TCOD_color_t fading_color; uint8_t fade; #ifdef TCOD_CONSOLE_SUPPORT TCOD_key_t key_state; #endif #ifdef TCOD_SDL2 /* application window was closed */ bool is_window_closed; /* application has mouse focus */ bool app_has_mouse_focus; /* application is active (not iconified) */ bool app_is_active; #endif } TCOD_internal_context_t; extern TCOD_internal_context_t TCOD_ctx; #if defined(__ANDROID__) && !defined(NDEBUG) #include #ifdef printf #undef printf #endif #ifdef vprintf #undef vprintf #endif #define printf(args...) __android_log_print(ANDROID_LOG_INFO, "libtcod", ## args) #define vprintf(args...) __android_log_vprint(ANDROID_LOG_INFO, "libtcod", ## args) #ifdef assert #undef assert #endif #define assert(cond) if(!(cond)) __android_log_assert(#cond, "libtcod", "assertion failed: %s", #cond) #endif #ifdef NDEBUG #define TCOD_IF(x) if (x) #define TCOD_IFNOT(x) if (!(x)) #define TCOD_ASSERT(x) #define TCOD_LOG(x) #else #define TCOD_IF(x) assert(x); #define TCOD_IFNOT(x) assert(x); if (0) #define TCOD_ASSERT(x) assert(x) #define TCOD_LOG(x) printf x #endif #if defined(TCOD_SDL2) && !defined(NO_OPENGL) /* opengl utilities */ void TCOD_opengl_init_attributes(void); bool TCOD_opengl_init_state(int conw, int conh, void *font_tex); void TCOD_opengl_uninit_state(void); bool TCOD_opengl_init_shaders(void); bool TCOD_opengl_render(int oldFade, bool *ascii_updated, TCOD_console_data_t *console, TCOD_console_data_t *cache); void TCOD_opengl_swap(void); void * TCOD_opengl_get_screen(void); #endif #ifdef TCOD_IMAGE_SUPPORT /* image internal stuff */ bool TCOD_image_mipmap_copy_internal(TCOD_image_t srcImage, TCOD_image_t dstImage); TCOD_color_t *TCOD_image_get_colors(TCOD_image_t *image); void TCOD_image_invalidate_mipmaps(TCOD_image_t *image); void TCOD_image_get_key_data(TCOD_image_t image, bool *has_key_color, TCOD_color_t *key_color); #endif /* fov internal stuff */ void TCOD_map_compute_fov_circular_raycasting(TCOD_map_t map, int player_x, int player_y, int max_radius, bool light_walls); void TCOD_map_compute_fov_diamond_raycasting(TCOD_map_t map, int player_x, int player_y, int max_radius, bool light_walls); void TCOD_map_compute_fov_recursive_shadowcasting(TCOD_map_t map, int player_x, int player_y, int max_radius, bool light_walls); void TCOD_map_compute_fov_permissive2(TCOD_map_t map, int player_x, int player_y, int max_radius, bool light_walls, int fovType); void TCOD_map_compute_fov_restrictive_shadowcasting(TCOD_map_t map, int player_x, int player_y, int max_radius, bool light_walls); void TCOD_map_postproc(map_t *map,int x0,int y0, int x1, int y1, int dx, int dy); #ifdef TCOD_CONSOLE_SUPPORT /* TCODConsole non public methods*/ bool TCOD_console_init(TCOD_console_t con,const char *title, bool fullscreen); int TCOD_console_print_internal(TCOD_console_t con,int x,int y, int w, int h, TCOD_bkgnd_flag_t flag, TCOD_alignment_t align, char *msg, bool can_split, bool count_only); int TCOD_console_stringLength(const unsigned char *s); unsigned char * TCOD_console_forward(unsigned char *s,int l); char *TCOD_console_vsprint(const char *fmt, va_list ap); #endif /* fatal errors */ void TCOD_fatal(const char *fmt, ...); void TCOD_fatal_nopar(const char *msg); /* TCODSystem non public methods */ #ifdef TCOD_CONSOLE_SUPPORT bool TCOD_sys_init(TCOD_console_data_t *console, bool fullscreen); void TCOD_sys_uninit(void); void TCOD_sys_set_custom_font(const char *font_name,int nb_ch, int nb_cv,int flags); void TCOD_sys_map_ascii_to_font(int asciiCode, int fontCharX, int fontCharY); void *TCOD_sys_create_bitmap_for_console(TCOD_console_t console); void TCOD_sys_save_bitmap(void *bitmap, const char *filename); void *TCOD_sys_create_bitmap(int width, int height, TCOD_color_t *buf); void TCOD_sys_delete_bitmap(void *bitmap); void TCOD_sys_console_to_bitmap(void *bitmap, TCOD_console_data_t *console, TCOD_console_data_t *cache); TCODLIB_API void *TCOD_sys_get_surface(int width, int height, bool alpha); void TCOD_sys_save_fps(void); void TCOD_sys_restore_fps(void); void TCOD_sys_set_dirty(int dx, int dy, int dw, int dh); void TCOD_sys_set_dirty_character_code(int ch); /* switch fullscreen mode */ void TCOD_sys_set_fullscreen(bool fullscreen); void TCOD_sys_set_clear_screen(void); void TCOD_sys_set_scale_factor(float value); void TCOD_sys_convert_console_to_screen_coords(int cx, int cy, int *sx, int *sy); void TCOD_sys_convert_screen_to_console_coords(int sx, int sy, int *cx, int *cy); void TCOD_sys_flush(bool render); TCOD_key_t TCOD_sys_check_for_keypress(int flags); TCOD_key_t TCOD_sys_wait_for_keypress(bool flush); bool TCOD_sys_is_key_pressed(TCOD_keycode_t key); void TCOD_sys_set_window_title(const char *title); #endif /* UTF-8 stuff */ #ifndef NO_UNICODE wchar_t *TCOD_console_vsprint_utf(const wchar_t *fmt, va_list ap); int TCOD_console_print_internal_utf(TCOD_console_t con,int x,int y, int rw, int rh, TCOD_bkgnd_flag_t flag, TCOD_alignment_t align, wchar_t *msg, bool can_split, bool count_only); #endif #ifdef TCOD_IMAGE_SUPPORT /* image manipulation */ TCODLIB_API void *TCOD_sys_load_image(const char *filename); void TCOD_sys_get_image_size(const void *image, int *w,int *h); TCOD_color_t TCOD_sys_get_image_pixel(const void *image,int x, int y); int TCOD_sys_get_image_alpha(const void *image,int x, int y); bool TCOD_sys_check_magic_number(const char *filename, size_t size, uint8_t *data); #endif /* TCOD_list nonpublic methods */ void TCOD_list_set_size(TCOD_list_t l, int size); #ifdef TCOD_SDL2 /* SDL12/SDL2 abstraction layer */ typedef struct TCOD_SDL_driver_t { float scale_xc; float scale_yc; /* get a fullscreen mode suitable for the console */ void (*get_closest_mode)(int *w, int *h); /* render the console on a surface/texture */ void (*render)(struct TCOD_SDL_driver_t *sdl, void *vbitmap, TCOD_console_data_t *console); /* create a new surface */ SDL_Surface *(*create_surface) (int width, int height, bool with_alpha); /* create the game window */ void (*create_window)(int w, int h, bool fullscreen); /* destroy the game window */ void (*destroy_window)(void); /* switch fullscreen on/off */ void (*set_fullscreen)(bool fullscreen); /* change the game window title */ void (*set_window_title)(const char *title); /* save game screenshot */ void (*save_screenshot)(const char *filename); /* get desktop resolution */ void (*get_current_resolution)(int *w, int *h); /* change the mouse cursor position */ void (*set_mouse_position)(int x, int y); /* clipboard */ char *(*get_clipboard_text)(void); bool (*set_clipboard_text)(const char *text); /* android compatible file access functions */ bool (*file_read)(const char *filename, unsigned char **buf, size_t *size); bool (*file_exists)(const char * filename); bool (*file_write)(const char *filename, unsigned char *buf, uint32_t size); /* clean stuff */ void (*shutdown)(void); /* get root cache */ TCOD_console_data_t *(*get_root_console_cache)(void); } TCOD_SDL_driver_t; /* defined in TCOD_sys_sdl12_c.c and TCOD_sys_sdl2_c.c */ TCOD_SDL_driver_t *SDL_implementation_factory(void); void find_resolution(void); void TCOD_sys_init_screen_offset(void); typedef struct { float force_recalc; float last_scale_xc, last_scale_yc; float last_scale_factor; float last_fullscreen; float min_scale_factor; float src_height_width_ratio; float dst_height_width_ratio; int src_x0, src_y0; int src_copy_width, src_copy_height; int src_proportionate_width, src_proportionate_height; int dst_display_width, dst_display_height; int dst_offset_x, dst_offset_y; int surface_width, surface_height; } scale_data_t; extern scale_data_t scale_data; extern float scale_factor; extern SDL_Surface* charmap; extern SDL_Window* window; extern SDL_Renderer* renderer; extern char *last_clipboard_text; #endif /* SDL & OpenGL */ extern int oldFade; /* color values */ #define TCOD_BLACK 0,0,0 #define TCOD_DARKEST_GREY 31,31,31 #define TCOD_DARKER_GREY 63,63,63 #define TCOD_DARK_GREY 95,95,95 #define TCOD_GREY 127,127,127 #define TCOD_LIGHT_GREY 159,159,159 #define TCOD_LIGHTER_GREY 191,191,191 #define TCOD_LIGHTEST_GREY 223,223,223 #define TCOD_WHITE 255,255,255 #define TCOD_DARKEST_SEPIA 31,24,15 #define TCOD_DARKER_SEPIA 63,50,31 #define TCOD_DARK_SEPIA 94,75,47 #define TCOD_SEPIA 127,101,63 #define TCOD_LIGHT_SEPIA 158,134,100 #define TCOD_LIGHTER_SEPIA 191,171,143 #define TCOD_LIGHTEST_SEPIA 222,211,195 /* desaturated */ #define TCOD_DESATURATED_RED 127,63,63 #define TCOD_DESATURATED_FLAME 127,79,63 #define TCOD_DESATURATED_ORANGE 127,95,63 #define TCOD_DESATURATED_AMBER 127,111,63 #define TCOD_DESATURATED_YELLOW 127,127,63 #define TCOD_DESATURATED_LIME 111,127,63 #define TCOD_DESATURATED_CHARTREUSE 95,127,63 #define TCOD_DESATURATED_GREEN 63,127,63 #define TCOD_DESATURATED_SEA 63,127,95 #define TCOD_DESATURATED_TURQUOISE 63,127,111 #define TCOD_DESATURATED_CYAN 63,127,127 #define TCOD_DESATURATED_SKY 63,111,127 #define TCOD_DESATURATED_AZURE 63,95,127 #define TCOD_DESATURATED_BLUE 63,63,127 #define TCOD_DESATURATED_HAN 79,63,127 #define TCOD_DESATURATED_VIOLET 95,63,127 #define TCOD_DESATURATED_PURPLE 111,63,127 #define TCOD_DESATURATED_FUCHSIA 127,63,127 #define TCOD_DESATURATED_MAGENTA 127,63,111 #define TCOD_DESATURATED_PINK 127,63,95 #define TCOD_DESATURATED_CRIMSON 127,63,79 /* lightest */ #define TCOD_LIGHTEST_RED 255,191,191 #define TCOD_LIGHTEST_FLAME 255,207,191 #define TCOD_LIGHTEST_ORANGE 255,223,191 #define TCOD_LIGHTEST_AMBER 255,239,191 #define TCOD_LIGHTEST_YELLOW 255,255,191 #define TCOD_LIGHTEST_LIME 239,255,191 #define TCOD_LIGHTEST_CHARTREUSE 223,255,191 #define TCOD_LIGHTEST_GREEN 191,255,191 #define TCOD_LIGHTEST_SEA 191,255,223 #define TCOD_LIGHTEST_TURQUOISE 191,255,239 #define TCOD_LIGHTEST_CYAN 191,255,255 #define TCOD_LIGHTEST_SKY 191,239,255 #define TCOD_LIGHTEST_AZURE 191,223,255 #define TCOD_LIGHTEST_BLUE 191,191,255 #define TCOD_LIGHTEST_HAN 207,191,255 #define TCOD_LIGHTEST_VIOLET 223,191,255 #define TCOD_LIGHTEST_PURPLE 239,191,255 #define TCOD_LIGHTEST_FUCHSIA 255,191,255 #define TCOD_LIGHTEST_MAGENTA 255,191,239 #define TCOD_LIGHTEST_PINK 255,191,223 #define TCOD_LIGHTEST_CRIMSON 255,191,207 /* lighter */ #define TCOD_LIGHTER_RED 255,127,127 #define TCOD_LIGHTER_FLAME 255,159,127 #define TCOD_LIGHTER_ORANGE 255,191,127 #define TCOD_LIGHTER_AMBER 255,223,127 #define TCOD_LIGHTER_YELLOW 255,255,127 #define TCOD_LIGHTER_LIME 223,255,127 #define TCOD_LIGHTER_CHARTREUSE 191,255,127 #define TCOD_LIGHTER_GREEN 127,255,127 #define TCOD_LIGHTER_SEA 127,255,191 #define TCOD_LIGHTER_TURQUOISE 127,255,223 #define TCOD_LIGHTER_CYAN 127,255,255 #define TCOD_LIGHTER_SKY 127,223,255 #define TCOD_LIGHTER_AZURE 127,191,255 #define TCOD_LIGHTER_BLUE 127,127,255 #define TCOD_LIGHTER_HAN 159,127,255 #define TCOD_LIGHTER_VIOLET 191,127,255 #define TCOD_LIGHTER_PURPLE 223,127,255 #define TCOD_LIGHTER_FUCHSIA 255,127,255 #define TCOD_LIGHTER_MAGENTA 255,127,223 #define TCOD_LIGHTER_PINK 255,127,191 #define TCOD_LIGHTER_CRIMSON 255,127,159 /* light */ #define TCOD_LIGHT_RED 255,63,63 #define TCOD_LIGHT_FLAME 255,111,63 #define TCOD_LIGHT_ORANGE 255,159,63 #define TCOD_LIGHT_AMBER 255,207,63 #define TCOD_LIGHT_YELLOW 255,255,63 #define TCOD_LIGHT_LIME 207,255,63 #define TCOD_LIGHT_CHARTREUSE 159,255,63 #define TCOD_LIGHT_GREEN 63,255,63 #define TCOD_LIGHT_SEA 63,255,159 #define TCOD_LIGHT_TURQUOISE 63,255,207 #define TCOD_LIGHT_CYAN 63,255,255 #define TCOD_LIGHT_SKY 63,207,255 #define TCOD_LIGHT_AZURE 63,159,255 #define TCOD_LIGHT_BLUE 63,63,255 #define TCOD_LIGHT_HAN 111,63,255 #define TCOD_LIGHT_VIOLET 159,63,255 #define TCOD_LIGHT_PURPLE 207,63,255 #define TCOD_LIGHT_FUCHSIA 255,63,255 #define TCOD_LIGHT_MAGENTA 255,63,207 #define TCOD_LIGHT_PINK 255,63,159 #define TCOD_LIGHT_CRIMSON 255,63,111 /* normal */ #define TCOD_RED 255,0,0 #define TCOD_FLAME 255,63,0 #define TCOD_ORANGE 255,127,0 #define TCOD_AMBER 255,191,0 #define TCOD_YELLOW 255,255,0 #define TCOD_LIME 191,255,0 #define TCOD_CHARTREUSE 127,255,0 #define TCOD_GREEN 0,255,0 #define TCOD_SEA 0,255,127 #define TCOD_TURQUOISE 0,255,191 #define TCOD_CYAN 0,255,255 #define TCOD_SKY 0,191,255 #define TCOD_AZURE 0,127,255 #define TCOD_BLUE 0,0,255 #define TCOD_HAN 63,0,255 #define TCOD_VIOLET 127,0,255 #define TCOD_PURPLE 191,0,255 #define TCOD_FUCHSIA 255,0,255 #define TCOD_MAGENTA 255,0,191 #define TCOD_PINK 255,0,127 #define TCOD_CRIMSON 255,0,63 /* dark */ #define TCOD_DARK_RED 191,0,0 #define TCOD_DARK_FLAME 191,47,0 #define TCOD_DARK_ORANGE 191,95,0 #define TCOD_DARK_AMBER 191,143,0 #define TCOD_DARK_YELLOW 191,191,0 #define TCOD_DARK_LIME 143,191,0 #define TCOD_DARK_CHARTREUSE 95,191,0 #define TCOD_DARK_GREEN 0,191,0 #define TCOD_DARK_SEA 0,191,95 #define TCOD_DARK_TURQUOISE 0,191,143 #define TCOD_DARK_CYAN 0,191,191 #define TCOD_DARK_SKY 0,143,191 #define TCOD_DARK_AZURE 0,95,191 #define TCOD_DARK_BLUE 0,0,191 #define TCOD_DARK_HAN 47,0,191 #define TCOD_DARK_VIOLET 95,0,191 #define TCOD_DARK_PURPLE 143,0,191 #define TCOD_DARK_FUCHSIA 191,0,191 #define TCOD_DARK_MAGENTA 191,0,143 #define TCOD_DARK_PINK 191,0,95 #define TCOD_DARK_CRIMSON 191,0,47 /* darker */ #define TCOD_DARKER_RED 127,0,0 #define TCOD_DARKER_FLAME 127,31,0 #define TCOD_DARKER_ORANGE 127,63,0 #define TCOD_DARKER_AMBER 127,95,0 #define TCOD_DARKER_YELLOW 127,127,0 #define TCOD_DARKER_LIME 95,127,0 #define TCOD_DARKER_CHARTREUSE 63,127,0 #define TCOD_DARKER_GREEN 0,127,0 #define TCOD_DARKER_SEA 0,127,63 #define TCOD_DARKER_TURQUOISE 0,127,95 #define TCOD_DARKER_CYAN 0,127,127 #define TCOD_DARKER_SKY 0,95,127 #define TCOD_DARKER_AZURE 0,63,127 #define TCOD_DARKER_BLUE 0,0,127 #define TCOD_DARKER_HAN 31,0,127 #define TCOD_DARKER_VIOLET 63,0,127 #define TCOD_DARKER_PURPLE 95,0,127 #define TCOD_DARKER_FUCHSIA 127,0,127 #define TCOD_DARKER_MAGENTA 127,0,95 #define TCOD_DARKER_PINK 127,0,63 #define TCOD_DARKER_CRIMSON 127,0,31 /* darkest */ #define TCOD_DARKEST_RED 63,0,0 #define TCOD_DARKEST_FLAME 63,15,0 #define TCOD_DARKEST_ORANGE 63,31,0 #define TCOD_DARKEST_AMBER 63,47,0 #define TCOD_DARKEST_YELLOW 63,63,0 #define TCOD_DARKEST_LIME 47,63,0 #define TCOD_DARKEST_CHARTREUSE 31,63,0 #define TCOD_DARKEST_GREEN 0,63,0 #define TCOD_DARKEST_SEA 0,63,31 #define TCOD_DARKEST_TURQUOISE 0,63,47 #define TCOD_DARKEST_CYAN 0,63,63 #define TCOD_DARKEST_SKY 0,47,63 #define TCOD_DARKEST_AZURE 0,31,63 #define TCOD_DARKEST_BLUE 0,0,63 #define TCOD_DARKEST_HAN 15,0,63 #define TCOD_DARKEST_VIOLET 31,0,63 #define TCOD_DARKEST_PURPLE 47,0,63 #define TCOD_DARKEST_FUCHSIA 63,0,63 #define TCOD_DARKEST_MAGENTA 63,0,47 #define TCOD_DARKEST_PINK 63,0,31 #define TCOD_DARKEST_CRIMSON 63,0,15 /* metallic */ #define TCOD_BRASS 191,151,96 #define TCOD_COPPER 197,136,124 #define TCOD_GOLD 229,191,0 #define TCOD_SILVER 203,203,203 /* miscellaneous */ #define TCOD_CELADON 172,255,175 #define TCOD_PEACH 255,159,127 #ifdef __cplusplus } #endif #endif libtcod-1.6.4+dfsg/include/libtcod_portability.h000066400000000000000000000114151321276576200217340ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef LIBTCOD_PORTABILITY_H #define LIBTCOD_PORTABILITY_H /* uncomment to disable unicode support */ /*#define NO_UNICODE */ /* uncomment to disable opengl support */ /*#define NO_OPENGL */ /* os identification TCOD_WINDOWS : OS is windows TCOD_LINUX : OS is Linux TCOD_MACOSX : OS is Mac OS X TCOD_HAIKU : OS is Haiku */ /* compiler identification TCOD_VISUAL_STUDIO : compiler is Microsoft Visual Studio TCOD_MINGW32 : compiler is Mingw32 TCOD_GCC : compiler is gcc/g++ */ /* word size TCOD_64BITS : 64 bits OS TCOD_WIN64 : 64 bits Windows TCOD_WIN32 : 32 bits Windows TCOD_LINUX64 : 64 bits Linux TCOD_LINUX32 : 32 bits Linux TCOD_FREEBSD64 : 64 bits FreeBSD TCOD_FREEBSD32 : 32 bits FreeBSD */ #if defined( _MSC_VER ) # define TCOD_VISUAL_STUDIO # define TCOD_WINDOWS # ifdef _WIN64 # define TCOD_WIN64 # define TCOD_64BITS # else # define TCOD_WIN32 # endif #elif defined( __MINGW32__ ) # define TCOD_WINDOWS # define TCOD_MINGW32 # ifdef _WIN64 # define TCOD_WIN64 # define TCOD_64BITS # else # define TCOD_WIN32 # endif #elif defined( __HAIKU__ ) # define TCOD_HAIKU # define TCOD_GCC # if __WORDSIZE == 64 # define TCOD_64BITS # endif #elif defined( __linux ) # define TCOD_LINUX # define TCOD_GCC # if __WORDSIZE == 64 # define TCOD_LINUX64 # define TCOD_64BITS # else # define TCOD_LINUX32 # endif #elif defined( __FreeBSD__ ) # define TCOD_FREEBSD # define TCOD_GCC # if __WORDSIZE == 64 # define TCOD_FREEBSD64 # define TCOD_64BITS # else # define TCOD_FREEBSD32 # endif #elif defined (__APPLE__) && defined (__MACH__) # define TCOD_MACOSX # define TCOD_GCC # if __WORDSIZE == 64 # define TCOD_64BITS # endif #endif /* unicode rendering functions support */ #ifndef NO_UNICODE #include #endif /* DLL export */ #ifndef TCODLIB_API #ifdef TCOD_WINDOWS #ifdef LIBTCOD_EXPORTS #define TCODLIB_API __declspec(dllexport) #else #define TCODLIB_API __declspec(dllimport) #endif #else #define TCODLIB_API #endif #endif /* For now this encapsulates mouse, keyboard, and consoles themselves. */ #undef TCOD_CONSOLE_SUPPORT #undef TCOD_IMAGE_SUPPORT #undef TCOD_OSUTIL_SUPPORT #ifdef TCOD_SDL2 #define TCOD_CONSOLE_SUPPORT #define TCOD_IMAGE_SUPPORT #define TCOD_OSUTIL_SUPPORT #else #define TCOD_BARE #endif /* int types */ #include "external/pstdint.h" /* bool type */ #ifndef __bool_true_false_are_defined #ifndef __cplusplus #if defined(_MSC_VER) && _MSC_VER < 1800 typedef uint8_t bool; #define true 1 #define false 0 #define __bool_true_false_are_defined 1 #else #include #endif #endif /* __cplusplus */ #endif /* __bool_true_false_are_defined */ #ifdef __cplusplus extern "C" { #endif /* ansi C lacks support for those functions */ TCODLIB_API char *TCOD_strdup(const char *s); TCODLIB_API int TCOD_strcasecmp(const char *s1, const char *s2); TCODLIB_API int TCOD_strncasecmp(const char *s1, const char *s2, size_t n); #if defined(TCOD_WINDOWS) char *strcasestr (const char *haystack, const char *needle); #endif #if defined(TCOD_LINUX) || defined(TCOD_HAIKU) || defined(TCOD_FREEBSD) || defined(TCOD_MACOSX) #define vsnwprintf vswprintf #endif #ifdef TCOD_WINDOWS #define vsnwprintf _vsnwprintf #endif #ifdef __cplusplus } #endif #endif /* LIBTCOD_PORTABILITY_H */ libtcod-1.6.4+dfsg/include/libtcod_utility.h000066400000000000000000000036241321276576200211000ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef LIBTCOD_UTILITY_H #define LIBTCOD_UTILITY_H /****************************************** utility macros ******************************************/ #define MAX(a,b) (((a)>(b))?(a):(b)) #define MIN(a,b) (((a)<(b))?(a):(b)) #define ABS(a) ((a)<0?-(a):(a)) #define CLAMP(a, b, x) ((x) < (a) ? (a) : ((x) > (b) ? (b) : (x))) #define LERP(a, b, x) ( (a) + (x) * ((b) - (a)) ) #endiflibtcod-1.6.4+dfsg/include/libtcod_version.h000066400000000000000000000034011321276576200210530ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef LIBTCOD_VERSION_H #define LIBTCOD_VERSION_H #define TCOD_HEXVERSION 0x010604 #define TCOD_STRVERSION "1.6.4" #define TCOD_TECHVERSION 0x01060400 #define TCOD_STRVERSIONNAME "libtcod "TCOD_STRVERSION #endif /* LIBTCOD_VERSION_H */ libtcod-1.6.4+dfsg/include/list.h000066400000000000000000000060471321276576200166520ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_LIST_H #define _TCOD_LIST_H #include "libtcod_portability.h" #ifdef __cplusplus extern "C" { #endif typedef void *TCOD_list_t; TCODLIB_API TCOD_list_t TCOD_list_new(void); TCODLIB_API TCOD_list_t TCOD_list_allocate(int nb_elements); TCODLIB_API TCOD_list_t TCOD_list_duplicate(TCOD_list_t l); TCODLIB_API void TCOD_list_delete(TCOD_list_t l); TCODLIB_API void TCOD_list_push(TCOD_list_t l, const void * elt); TCODLIB_API void * TCOD_list_pop(TCOD_list_t l); TCODLIB_API void * TCOD_list_peek(TCOD_list_t l); TCODLIB_API void TCOD_list_add_all(TCOD_list_t l, TCOD_list_t l2); TCODLIB_API void * TCOD_list_get(TCOD_list_t l,int idx); TCODLIB_API void TCOD_list_set(TCOD_list_t l,const void *elt, int idx); TCODLIB_API void ** TCOD_list_begin(TCOD_list_t l); TCODLIB_API void ** TCOD_list_end(TCOD_list_t l); TCODLIB_API void TCOD_list_reverse(TCOD_list_t l); TCODLIB_API void **TCOD_list_remove_iterator(TCOD_list_t l, void **elt); TCODLIB_API void TCOD_list_remove(TCOD_list_t l, const void * elt); TCODLIB_API void **TCOD_list_remove_iterator_fast(TCOD_list_t l, void **elt); TCODLIB_API void TCOD_list_remove_fast(TCOD_list_t l, const void * elt); TCODLIB_API bool TCOD_list_contains(TCOD_list_t l,const void * elt); TCODLIB_API void TCOD_list_clear(TCOD_list_t l); TCODLIB_API void TCOD_list_clear_and_delete(TCOD_list_t l); TCODLIB_API int TCOD_list_size(TCOD_list_t l); TCODLIB_API void ** TCOD_list_insert_before(TCOD_list_t l,const void *elt,int before); TCODLIB_API bool TCOD_list_is_empty(TCOD_list_t l); #ifdef __cplusplus } #endif #endif libtcod-1.6.4+dfsg/include/list.hpp000066400000000000000000000524751321276576200172200ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_LIST_HPP #define _TCOD_LIST_HPP #include "list.h" #include // memcpy #include // NULL /** @PageName list @PageCategory Base toolkits @PageTitle All purposes container @PageDesc This is a fast, lightweight and generic container, that provides array, list and stack paradigms. Note that this module has no Python wrapper. Use Python built-in containers instead. */ // fast & lightweight list template template class TCODList { T *array; int fillSize; int allocSize; public : /** @PageName list_create @PageFather list @PageTitle Creating a list @FuncTitle Using the default constructor @FuncDesc You can create an empty list with the default constructor. The C version returns a handler on the list. @Cpp template TCODList::TCODList() @C TCOD_list_t TCOD_list_new() @CppEx TCODList intList; TCODList *floatList = new TCODList(); @CEx TCOD_list_t intList = TCOD_list_new(); TCOD_list_t floatList = TCOD_list_new(); */ TCODList() { array=NULL; fillSize=allocSize=0; } /** @PageName list_create @FuncTitle Duplicating an existing list @FuncDesc You can create a list by duplicating an existing list. @Cpp template TCODList::TCODList(const TCODList &l) @C TCOD_list_t TCOD_list_duplicate(TCOD_list_t l) @Param l Existing list to duplicate. @CppEx TCODList intList; intList.push(3); intList.push(5); TCODList intList2(intList); // intList2 contains two elements : 3 and 5 @CEx TCOD_list_t intList = TCOD_list_new(); TCOD_list_push(intList,(const void *)3); TCOD_list_push(intList,(const void *)5); TCOD_list_t intList2 = TCOD_list_duplicate(intList); // intList2 contains two elements : 3 and 5 */ TCODList(const TCOD_list_t l) { array=NULL; fillSize=allocSize=0; for ( void **it=TCOD_list_begin(l); it != TCOD_list_end(l); it++ ) { push(*((T *)(it))); } } TCODList(const TCODList &l2) { array=NULL; fillSize=allocSize=0; *this = l2; } /** @PageName list_create @FuncTitle Preallocating memory @FuncDesc You can also create an empty list and pre-allocate memory for elements. Use this if you know the list size and want the memory to fit it perfectly. @Cpp template TCODList::TCODList(int nbElements) @C TCOD_list_t TCOD_list_allocate(int nbElements) @Param nbElements Allocate memory for nbElements. @CppEx TCODList intList(5); // create an empty list, pre-allocate memory for 5 elements @CEx TCOD_list_t intList = TCOD_list_allocate(5); */ TCODList(int nbElements) { fillSize=0; allocSize=nbElements; array=new T[ nbElements ]; } /** @PageName list_create @FuncTitle Deleting a list @FuncDesc You can delete a list, freeing any allocated resources. Note that deleting the list does not delete it's elements. You have to use clearAndDelete before deleting the list if you want to destroy the elements too. @Cpp virtual template TCODList::~TCODList() @C void TCOD_list_delete(TCOD_list_t l) @Param l In the C version, the list handler, returned by a constructor. @CppEx TCODList *intList = new TCODList(); // allocate a new empty list intList->push(5); // the list contains 1 element at position 0, value = 5 delete intList; // destroy the list @CEx TCOD_list_t intList = TCOD_list_new(); TCOD_list_push(intList,(const void *)5); TCOD_list_delete(intList); */ virtual ~TCODList() { if ( array ) delete [] array; } /** @PageName list_array @PageTitle Basic array operations @PageFather list @FuncTitle Setting an element @FuncDesc You can assign a value with set. If needed, the array will allocate new elements up to idx. @Cpp template void TCODList::set(const T elt, int idx) @C void TCOD_list_set(TCOD_list_t l,const void *elt, int idx) @Param elt Element to put in the array. @Param idx Index of the element. 0 <= idx @Param l In the C version, the handler, returned by a constructor. @CppEx TCODList intList; // the array is empty (contains 0 elements) intList.set(5,0); // the array contains 1 element at position 0, value = 5 intList.set(7,2); // the array contains 3 elements : 5, 0, 7 @CEx TCOD_list_t intList = TCOD_list_new(); TCOD_list_set(intList,(const void *)5,0); TCOD_list_set(intList,(const void *)7,2); */ void set(const T elt, int idx) { if ( idx < 0 ) return; while ( allocSize < idx+1 ) allocate(); array[idx] = elt; if ( idx+1 > fillSize ) fillSize = idx+1; } /** @PageName list_array @FuncTitle Getting an element value @FuncDesc You can retrieve a value with get. @Cpp template T TCODList::get(int idx) const @C void * TCOD_list_get(TCOD_list_t l,int idx) @Param idx Index of the element. 0 <= idx < size of the array @Param l In the C version, the handler, returned by a constructor. @CppEx TCODList intList; intList.set(5,0); int val = intList.get(0); // val == 5 @CEx TCOD_list_t intList = TCOD_list_new(); TCOD_list_set(intList,(const void *)5,0); int val = (int)TCOD_list_get(intList,0); // val == 5 */ T get(int idx) const { return array[idx]; } /** @PageName list_array @FuncTitle Checking if a list is empty @Cpp template bool TCODList::isEmpty() const @C bool TCOD_list_is_empty(TCOD_list_t l) @Param l In the C version, the handler, returned by a constructor. @CppEx TCODList intList; bool empty=intList.isEmpty(); // empty == true intList.set(3,0); empty=intList.isEmpty(); // empty == false @CEx TCOD_list_t intList = TCOD_list_new(); bool empty=TCOD_list_is_empty(intList); // empty == true TCOD_list_set(intList,(const void *)5,0); empty=TCOD_list_is_empty(intList); // empty == false */ bool isEmpty() const { return ( fillSize == 0 ); } /** @PageName list_array @FuncTitle Getting the list size @Cpp template int TCODList::size() const @C int TCOD_list_size(TCOD_list_t l) @Param l In the C version, the handler, returned by a constructor. @CppEx TCODList intList; int size=intList.size(); // size == 0 intList.set(3,0); size=intList.size(); // size == 1 @CEx TCOD_list_t intList = TCOD_list_new(); int size=TCOD_list_size(intList); // size == 0 TCOD_list_set(intList,(const void *)5,0); size=TCOD_list_size(intList); // size == 1 */ int size() const { return fillSize; } /** @PageName list_array @FuncTitle Checking if an element is in the list @Cpp template bool TCODList::contains(const T elt) const @C bool TCOD_list_contains(TCOD_list_t l,const void * elt) @Param elt The element. @Param l In the C version, the handler, returned by a constructor. @CppEx TCODList intList; intList.set(3,0); bool has3 = intList.contains(3); // has3 == true bool has4 = intList.contains(4); // has4 == false @CEx TCOD_list_t intList = TCOD_list_new(); TCOD_list_set(intList,(const void *)3,0); bool has3 = TCOD_list_contains(intList,(const void *)3); // has3 == true bool has4 = TCOD_list_contains(intList,(const void *)4); // has4 == false */ bool contains(const T elt) const { for ( T* curElt = begin(); curElt != end(); curElt ++) { if ( *curElt == elt ) return true; } return false; } /** @PageName list_list @PageFather list @PageTitle Basic list operations @FuncTitle Insert an element in the list @Cpp template void TCODList::insertBefore(const T elt,int before) @C void TCOD_list_insert_before(TCOD_list_t l,const void *elt,int before) @Param elt Element to insert in the list. @Param idx Index of the element after the insertion. 0 <= idx < list size @Param l In the C version, the list handler, returned by a constructor. @CppEx TCODList intList; // the list is empty (contains 0 elements) intList.set(0,5); // the list contains 1 element at position 0, value = 5 intList.insertBefore(2,0); // the list contains 2 elements : 2,5 @CEx TCOD_list_t intList = TCOD_list_new(); TCOD_list_set(intList,0,(const void *)5); TCOD_list_insert_before(intList,(const void *)2,0); */ T * insertBefore(const T elt,int before) { if ( fillSize+1 >= allocSize ) allocate(); for (int idx=fillSize; idx > before; idx--) { array[idx]=array[idx-1]; } array[before]=elt; fillSize++; return &array[before]; } /** @PageName list_list @FuncTitle Removing an element from the list @FuncDesc The _fast versions replace the element to remove with the last element of the list. They're faster, but do not preserve the list order. @Cpp template void TCODList::remove(const T elt) template void TCODList::removeFast(const T elt) @C void TCOD_list_remove(TCOD_list_t l, const void * elt) void TCOD_list_remove_fast(TCOD_list_t l, const void * elt) @Param elt The element to remove @Param l In the C version, the list handler, returned by a constructor. @CppEx TCODList intList; // the list is empty (contains 0 elements) intList.set(0,5); // the list contains 1 element at position 0, value = 5 intList.remove(5); // the list is empty @CEx TCOD_list_t intList = TCOD_list_new(); TCOD_list_set(intList,0,(const void *)5); TCOD_list_remove(intList,(const void *)5); */ void remove(const T elt) { for ( T* curElt = begin(); curElt != end(); curElt ++) { if ( *curElt == elt ) { remove(curElt); return; } } } void removeFast(const T elt) { for ( T* curElt = begin(); curElt != end(); curElt ++) { if ( *curElt == elt ) { removeFast(curElt); return; } } } /** @PageName list_list @FuncTitle Concatenating two lists @FuncDesc You can concatenate two lists. Every element of l2 will be added to current list (or l in the C version) : @Cpp template void TCODList::addAll(const TCODList &l2) @C void TCOD_list_add_all(TCOD_list_t l, TCOD_list_t l2) @Param l The list inside which elements will be added. @Param l2 the list handler containing elements to insert. @CppEx TCODList intList; intList.set(1,3); // intList contains 2 elements : 0, 3 TCODList intList2; // intList2 is empty intList2.set(0,1); // intList2 contains 1 element : 1 intList2.addAll(intList); // intList2 contains 3 elements : 1, 0, 3 @CEx TCOD_list_t intList = TCOD_list_new(); TCOD_list_set(intList,1,(const void *)3); TCOD_list_t intList2 = TCOD_list_new(); TCOD_list_set(intList2,0,(const void *)1); TCOD_list_add_all(intList2,intList); */ void addAll(const TCODList &l2) { for (T *t=l2.begin(); t!= l2.end(); t++) { push(*t); } } /** @PageName list_list @FuncTitle Emptying a list @Cpp template void TCODList::clear() @C void TCOD_list_clear(TCOD_list_t l) @Param l In the C version, the list handler, returned by a constructor. @CppEx TCODList intList; intList.set(0,3); // intList contains 1 element intList.clear(); // intList is empty @CEx TCOD_list_t intList = TCOD_list_new(); TCOD_list_set(intList,0,(const void *)5); TCOD_list_clear(intList); */ void clear() { fillSize=0; } /** @PageName list_list @FuncTitle Emptying a list and destroying its elements @FuncDesc For lists containing pointers, you can clear the list and delete (or free for C) the elements : @Cpp template void TCODList::clearAndDelete() @C void TCOD_list_clear_and_delete(TCOD_list_t l) @Param l In the C version, the list handler, returned by a constructor. @CppEx TCODList intList; MyClass * cl=new MyClass(); // new instance of MyClass allocated here intList.set(0,cl); intList.clear(); // the list is empty. cl is always valid intList.set(0,cl); intList.clearAndDelete(); // the list is empty. delete cl has been called. The address cl is no longer valid. @C TCOD_list_t intList = TCOD_list_new(); void *data=calloc(10,1); // some memory allocation here TCOD_list_set(intList,0,(const void *)data); TCOD_list_clear(intList); // the list is empty, but data is always valid TCOD_list_set(intList,0,(const void *)data); TCOD_list_clear_and_delete(intList); // the list is empty, free(data) has been called. The address data is no longer valid */ void clearAndDelete() { for ( T* curElt = begin(); curElt != end(); curElt ++ ) { delete (*curElt); } fillSize=0; } /** @PageName list_list @FuncTitle Reversing a list @FuncDesc This function reverses the order of the elements in the list. @Cpp void TCODList::reverse() @C void TCOD_list_reverse(TCOD_list_t l) @Param l In the C version, the list handler, returned by a constructor. @CppEx TCODList intList; // the list is empty (contains 0 elements) intList.push(5); // the list contains 1 element at position 0, value = 5 intList.push(2); // the list contains 2 elements : 5,2 intList.reverse(); // now order is 2,5 @CEx TCOD_list_t intList = TCOD_list_new(); TCOD_list_push(intList,(const void *)5); TCOD_list_push(intList,(const void *)2); TCOD_list_reverse(); */ void reverse() { T* head = begin(); T* tail = end(); while ( head < tail ) { T tmp = *head; *head=*tail; *tail=tmp; head++; tail--; } } /** @PageName list_stack @PageTitle Basic stack operations @PageFather list @FuncTitle Pushing an element on the stack @FuncDesc You can push an element on the stack (append it to the end of the list) : @Cpp template void TCODList::push(const T elt) @C void TCOD_list_push(TCOD_list_t l, const void * elt) @Param elt Element to append to the list. @Param l In the C version, the list handler, returned by a constructor. @CppEx TCODList intList; // the list is empty (contains 0 elements) intList.push(5); // the list contains 1 element at position 0, value = 5 intList.push(2); // the list contains 2 elements : 5,2 @CEx TCOD_list_t intList = TCOD_list_new(); TCOD_list_push(intList,(const void *)5); TCOD_list_push(intList,(const void *)2); */ void push(const T elt) { if ( fillSize+1 >= allocSize ) allocate(); array[fillSize++] = elt; } /** @PageName list_stack @FuncTitle Poping an element from the stack @FuncDesc You can pop an element from the stack (remove the last element of the list). @Cpp template T TCODList::pop() @C void * TCOD_list_pop(TCOD_list_t l) @Param l In the C version, the list handler, returned by a constructor. @CppEx TCODList intList; // the list is empty (contains 0 elements) intList.push(5); // the list contains 1 element at position 0, value = 5 intList.push(2); // the list contains 2 elements : 5,2 int val = intList.pop(); // val == 2, the list contains 1 element : 5 val = intList.pop(); // val == 5, the list is empty @CEx TCOD_list_t intList = TCOD_list_new(); TCOD_list_push(intList,(const void *)5); TCOD_list_push(intList,(const void *)2); int val = (int)TCOD_list_pop(intList); val = (int)TCOD_list_pop(intList); */ T pop() { if ( fillSize == 0 ) return (T)0; return array[--fillSize]; } /** @PageName list_stack @FuncTitle Peeking the last element of the stack @FuncDesc You can read the last element of the stack without removing it : @Cpp template T TCODList::peek() const @C void * TCOD_list_peek(TCOD_list_t l) @Param l In the C version, the list handler, returned by a constructor. @CppEx TCODList intList; intList.push(3); // intList contains 1 elements : 3 int val = intList.peek(); // val == 3, inList contains 1 elements : 3 intList.push(2); // intList contains 2 elements : 3, 2 val = intList.peek(); // val == 2, inList contains 2 elements : 3, 2 @CEx TCOD_list_t intList = TCOD_list_new(); TCOD_list_push(intList,(const void *)3); int val = (int)TCOD_list_peek(intList); TCOD_list_push(intList,(const void *)2); val = (int)TCOD_list_peek(intList); */ T peek() const { if ( fillSize == 0 ) return (T)0; return array[fillSize-1]; } /** @PageName list_iterator @PageFather list @PageTitle Iterators @FuncDesc You can iterate through the elements of the list using an iterator. begin() returns the address of the first element of the list. You go to the next element using the increment operator ++. When the iterator's value is equal to end(), you've gone through all the elements. Warning ! You cannot insert elements in the list while iterating through it. Inserting elements can result in reallocation of the list and your iterator will not longer be valid. @Cpp template T * TCODList::begin() const template T * TCODList::end() const @C void ** TCOD_list_begin(TCOD_list_t l) void ** TCOD_list_end(TCOD_list_t l) @Param l In the C version, the list handler, returned by a constructor. @CppEx TCODList intList; // the list is empty (contains 0 elements) intList.push(5); // the list contains 1 element at position 0, value = 5 intList.push(2); // the list contains 2 elements : 5,2 for ( int * iterator = intList.begin(); iterator != intList.end(); iterator ++ ) { int currentValue=*iterator; printf("value : %d\n", currentValue ); } @CEx TCOD_list_t intList = TCOD_list_new(); TCOD_list_push(intList,(const void *)5); TCOD_list_push(intList,(const void *)2); for ( int * iterator = (int *)TCOD_list_begin(intList); iterator != (int *)TCOD_list_end(intList); iterator ++ ) { int currentValue=*iterator; printf("value : %d\n", currentValue ); } */ T * begin() const { if ( fillSize == 0 ) return (T *)NULL; return &array[0]; } T * end() const { if ( fillSize == 0 ) return (T *)NULL; return &array[fillSize]; } /** @PageName list_iterator @FuncDesc You can remove an element from the list while iterating. The element at the iterator position will be removed. The function returns the new iterator. The _fast versions replace the element to remove with the last element of the list. They're faster, but do not preserve the list order. @Cpp template T *TCODList::remove(T *iterator) template T *TCODList::removeFast(T *iterator) @C void **TCOD_list_remove_iterator(TCOD_list_t l, void **iterator) void **TCOD_list_remove_iterator_fast(TCOD_list_t l, void **iterator) @Param iterator The list iterator. @Param l In the C version, the list handler, returned by a constructor. @CppEx TCODList intList; // the list is empty (contains 0 elements) intList.push(5); // the list contains 1 element at position 0, value = 5 intList.push(2); // the list contains 2 elements : 5,2 intList.push(3); // the list contains 3 elements : 5,2,3 for ( int * iterator = intList.begin(); iterator != intList.end(); iterator ++ ) { int currentValue=*iterator; if ( currentValue == 2 ) { // remove this value from the list and keep iterating on next element (value == 3) iterator = intList.remove(iterator); } printf("value : %d\n", currentValue ); // all 3 values will be printed : 5,2,3 } // now the list contains only two elements : 5,3 @CEx TCOD_list_t intList = TCOD_list_new(); TCOD_list_push(intList,(const void *)5); TCOD_list_push(intList,(const void *)2); TCOD_list_push(intList,(const void *)3); for ( int * iterator = (int *)TCOD_list_begin(intList); iterator != (int *)TCOD_list_end(intList); iterator ++ ) { int currentValue=*iterator; if ( currentValue == 2 ) { iterator = (int *)TCOD_list_remove_iterator(intList,(void **)iterator); } printf("value : %d\n", currentValue ); } */ T *remove(T *elt) { for ( T* curElt = elt; curElt < end()-1; curElt ++) { *curElt = *(curElt+1); } fillSize--; if ( fillSize == 0 ) return ((T *)NULL)-1; else return elt-1; } T *removeFast(T *elt) { *elt = array[fillSize-1]; fillSize--; if ( fillSize == 0 ) return ((T *)NULL)-1; else return elt-1; } TCODList & operator = (TCODList const & l2) { while ( allocSize < l2.allocSize ) allocate(); fillSize=l2.fillSize; int i=0; for (T *t=l2.begin(); t != l2.end(); t++) { array[i++]=*t; } return *this; } protected : void allocate() { int newSize = allocSize * 2; if ( newSize == 0 ) newSize = 16; T *newArray = new T[ newSize ]; if ( array ) { if ( fillSize > 0 ) memcpy(newArray, array, sizeof(T)*fillSize); delete [] array; } array=newArray; allocSize=newSize; } }; #endif libtcod-1.6.4+dfsg/include/mersenne.h000066400000000000000000000057731321276576200175200ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_RANDOM_H #define _TCOD_RANDOM_H #include "libtcod_portability.h" #include "mersenne_types.h" #ifdef __cplusplus extern "C" { #endif TCODLIB_API TCOD_random_t TCOD_random_get_instance(void); TCODLIB_API TCOD_random_t TCOD_random_new(TCOD_random_algo_t algo); TCODLIB_API TCOD_random_t TCOD_random_save(TCOD_random_t mersenne); TCODLIB_API void TCOD_random_restore(TCOD_random_t mersenne, TCOD_random_t backup); TCODLIB_API TCOD_random_t TCOD_random_new_from_seed(TCOD_random_algo_t algo, uint32_t seed); TCODLIB_API void TCOD_random_delete(TCOD_random_t mersenne); TCODLIB_API void TCOD_random_set_distribution (TCOD_random_t mersenne, TCOD_distribution_t distribution); TCODLIB_API int TCOD_random_get_int (TCOD_random_t mersenne, int min, int max); TCODLIB_API float TCOD_random_get_float (TCOD_random_t mersenne, float min, float max); TCODLIB_API double TCOD_random_get_double (TCOD_random_t mersenne, double min, double max); TCODLIB_API int TCOD_random_get_int_mean (TCOD_random_t mersenne, int min, int max, int mean); TCODLIB_API float TCOD_random_get_float_mean (TCOD_random_t mersenne, float min, float max, float mean); TCODLIB_API double TCOD_random_get_double_mean (TCOD_random_t mersenne, double min, double max, double mean); TCODLIB_API TCOD_dice_t TCOD_random_dice_new (const char * s); TCODLIB_API int TCOD_random_dice_roll (TCOD_random_t mersenne, TCOD_dice_t dice); TCODLIB_API int TCOD_random_dice_roll_s (TCOD_random_t mersenne, const char * s); #ifdef __cplusplus } #endif #endif libtcod-1.6.4+dfsg/include/mersenne.hpp000066400000000000000000000466421321276576200200600ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_RANDOM_HPP #define _TCOD_RANDOM_HPP #include "mersenne.h" /** @PageName random @PageCategory Base toolkits @PageTitle Pseudorandom number generator @PageDesc This toolkit is an implementation of two fast and high quality pseudorandom number generators: * a Mersenne twister generator, * a Complementary-Multiply-With-Carry generator. CMWC is faster than MT (see table below) and has a much better period (1039460 vs. 106001). It is the default algo since libtcod 1.5.0. Relative performances in two independent tests (lower is better) :
Algorithm Numbers generated Perf (1) Perf (2)
MT integer 62 50
MT float 54 45
CMWC integer 21 34
CMWC float 32 27
For Python users:
Python already has great builtin random generators. But some parts of the Doryen library (noise, heightmap, ...) uses RNG as parameters. If you intend to use those functions, you must provide a RNG created with the library.
For C# users:
.NET already has great builtin random generators. But some parts of the Doryen library (noise, heightmap, ...) uses RNG as parameters. If you intend to use those functions, you must provide a RNG created with the library. */ class TCODLIB_API TCODRandom { public : /** @PageName random_init @PageFather random @PageTitle Creating a generator @FuncTitle Default generator @FuncDesc The simplest way to get random number is to use the default generator. The first time you get this generator, it is initialized by calling TCOD_random_new. Then, on successive calls, this function returns the same generator (singleton pattern). @Cpp static TCODRandom * TCODRandom::getInstance (void) @C TCOD_random_t TCOD_random_get_instance (void) @Py random_get_instance () @C# static TCODRandom TCODRandom::getInstance() @Param algo The PRNG algorithm the generator should be using. Possible values are: * TCOD_RNG_MT for Mersenne Twister, * TCOD_RNG_CMWC for Complementary Multiply-With-Carry. */ static TCODRandom * getInstance(void); /** @PageName random_init @FuncTitle Generators with random seeds @FuncDesc You can also create as many generators as you want with a random seed (the number of seconds since Jan 1 1970 at the time the constructor is called). Warning ! If you call this function several times in the same second, it will return the same generator. @Cpp TCODRandom::TCODRandom (TCOD_random_algo_t algo = TCOD_RNG_CMWC) @C TCOD_random_t TCOD_random_new (TCOD_random_algo_t algo) @Py random_new (algo = RNG_CMWC) @C# TCODRandom::TCODRandom() // Defaults to ComplementaryMultiplyWithCarry TCODRandom::TCODRandom(TCODRandomType algo) @Param algo The PRNG algorithm the generator should be using. */ TCODRandom(TCOD_random_algo_t algo = TCOD_RNG_CMWC, bool allocate = true); /** @PageName random_init @FuncTitle Generators with user defined seeds @FuncDesc Finally, you can create generators with a specific seed. Those allow you to get a reproducible set of random numbers. You can for example save a dungeon in a file by saving only the seed used for its generation (provided you have a determinist generation algorithm) @Cpp TCODRandom::TCODRandom (uint32_t seed, TCOD_random_algo_t algo = TCOD_RNG_CMWC); @C TCOD_random_t TCOD_random_new_from_seed (TCOD_random_algo_t algo, uint32_t seed); @Py random_new_from_seed(seed, algo=RNG_CMWC) @C# TCODRandom::TCODRandom(uint32_t seed) // Defaults to ComplementaryMultiplyWithCarry TCODRandom::TCODRandom(uint32_t seed, TCODRandomType algo) @Param seed The 32 bits seed used to initialize the generator. Two generators created with the same seed will generate the same set of pseudorandom numbers. @Param algo The PRNG algorithm the generator should be using. @CppEx // default generator TCODRandom * default = TCODRandom::getInstance(); // another random generator TCODRandom * myRandom = new TCODRandom(); // a random generator with a specific seed TCODRandom * myDeterministRandom = new TCODRandom(0xdeadbeef); @CEx // default generator TCOD_random_t default = TCOD_random_get_instance(); // another random generator TCOD_random_t my_random = TCOD_random_new(TCOD_RNG_CMWC); // a random generator with a specific seed TCOD_random_t my_determinist_random = TCOD_random_new_from_seed(TCOD_RNG_CMWC,0xdeadbeef); @PyEx # default generator default = libtcod.random_get_instance() # another random generator my_random = libtcod.random_new() # a random generator with a specific seed my_determinist_random = libtcod.random_new_from_seed(0xdeadbeef) */ TCODRandom(uint32_t seed, TCOD_random_algo_t algo = TCOD_RNG_CMWC); /** @PageName random_init @FuncTitle Destroying a RNG @FuncDesc To release resources used by a generator, use those functions : NB : do not delete the default random generator ! @Cpp TCODRandom::~TCODRandom() @C void TCOD_random_delete(TCOD_random_t mersenne) @Py random_delete(mersenne) @C# void TCODRandom::Dispose() @Param mersenne In the C and Python versions, the generator handler, returned by the initialization functions. @CppEx // create a generator TCODRandom *rnd = new TCODRandom(); // use it ... // destroy it delete rnd; @CEx // create a generator TCOD_random_t rnd = TCOD_random_new(); // use it ... // destroy it TCOD_random_delete(rnd); @PyEx # create a generator rnd = libtcod.random_new() # use it ... # destroy it libtcod.random_delete(rnd) */ virtual ~TCODRandom(); /** @PageName random_distro @PageFather random @PageTitle Using a generator @FuncTitle Setting the default RNG distribution @FuncDesc Random numbers can be obtained using several different distributions. Linear is default, but if you wish to use one of the available Gaussian distributions, you can use this function to tell libtcod which is your preferred distribution. All random number getters will then use that distribution automatically to fetch your random numbers. The distributions available are as follows: 1. TCOD_DISTRIBUTION_LINEAR This is the default distribution. It will return a number from a range min-max. The numbers will be evenly distributed, ie, each number from the range has the exact same chance of being selected. 2. TCOD_DISTRIBUTION_GAUSSIAN This distribution does not have minimum and maximum values. Instead, a mean and a standard deviation are used. The mean is the central value. It will appear with the greatest frequency. The farther away from the mean, the less the probability of appearing the possible results have. Although extreme values are possible, 99.7% of the results will be within the radius of 3 standard deviations from the mean. So, if the mean is 0 and the standard deviation is 5, the numbers will mostly fall in the (-15,15) range. 3. TCOD_DISTRIBUTION_GAUSSIAN_RANGE This one takes minimum and maximum values. Under the hood, it computes the mean (which falls right between the minimum and maximum) and the standard deviation and applies a standard Gaussian distribution to the values. The difference is that the result is always guaranteed to be in the min-max range. 4. TCOD_DISTRIBUTION_GAUSSIAN_INVERSE Essentially, this is the same as TCOD_DISTRIBUTION_GAUSSIAN. The difference is that the values near +3 and -3 standard deviations from the mean have the highest possibility of appearing, while the mean has the lowest. 5. TCOD_DISTRIBUTION_GAUSSIAN_RANGE_INVERSE Essentially, this is the same as TCOD_DISTRIBUTION_GAUSSIAN_RANGE, but the min and max values have the greatest probability of appearing, while the values between them, the lowest. There exist functions to also specify both a min-max range AND a custom mean, which can be any value (possibly either min or max, but it can even be outside that range). In case such a function is used, the distributions will trigger a slihtly different behaviour: * TCOD_DISTRIBUTION_LINEAR * TCOD_DISTRIBUTION_GAUSSIAN * TCOD_DISTRIBUTION_GAUSSIAN_RANGE In these cases, the selected mean will have the highest probability of appearing. * TCOD_DISTRIBUTION_GAUSSIAN_INVERSE * TCOD_DISTRIBUTION_GAUSSIAN_RANGE_INVERSE In these cases, the selected mean will appear with the lowest frequency. @Cpp void TCODRandom::setDistribution(TCOD_distribution_t distribution) @C void TCOD_random_set_distribution(TCOD_random_t mersenne, TCOD_distribution_t distribution) @Py @C# @Param mersenne In the C and Python versions, the generator handler, returned by the initialization functions. If NULL, the default generator is used.. @Param distribution The distribution constant from the available set:
  • TCOD_DISTRIBUTION_LINEAR
  • TCOD_DISTRIBUTION_GAUSSIAN
  • TCOD_DISTRIBUTION_GAUSSIAN_RANGE
  • TCOD_DISTRIBUTION_GAUSSIAN_INVERSE
  • TCOD_DISTRIBUTION_GAUSSIAN_RANGE_INVERSE
*/ inline void setDistribution (TCOD_distribution_t distribution) { TCOD_random_set_distribution(data,distribution); } /** @PageName random_use @PageFather random @PageTitle Using a generator @FuncTitle Getting an integer @FuncDesc Once you obtained a generator (using one of those methods), you can get random numbers using the following functions, using either the explicit or simplified API where applicable: @Cpp //explicit API: int TCODRandom::getInt(int min, int max, int mean = 0) //simplified API: int TCODRandom::get(int min, int max, int mean = 0) @C int TCOD_random_get_int(TCOD_random_t mersenne, int min, int max) int TCOD_random_get_int_mean(TCOD_random_t mersenne, int min, int max, int mean) @Py @C# @Param mersenne In the C and Python versions, the generator handler, returned by the initialization functions. If NULL, the default generator is used.. @Param min,max Range of values returned. Each time you call this function, you get a number between (including) min and max @Param mean This is used to set a custom mean, ie, not min+((max-min)/2). It can even be outside of the min-max range. Using a mean will force the use of a weighted (Gaussian) distribution, even if linear is set. */ inline int getInt (int min, int max, int mean = 0) { return (mean <= 0) ? TCOD_random_get_int(data,min,max) : TCOD_random_get_int_mean(data,min,max,mean); } inline int get (int min, int max, int mean = 0) { return (mean <= 0) ? TCOD_random_get_int(data,min,max) : TCOD_random_get_int_mean(data,min,max,mean); } /** @PageName random_use @FuncTitle Getting a float @FuncDesc To get a random floating point number, using either the explicit or simplified API where applicable @Cpp //explicit API: float TCODRandom::getFloat(float min, float max, float mean = 0.0f) //simplified API: float TCODRandom::get(float min, float max, float mean = 0.0f) @C float TCOD_random_get_float(TCOD_random_t mersenne, float min, float max) float TCOD_random_get_float_mean(TCOD_random_t mersenne, float min, float max, float mean) @Py random_get_float(mersenne, mi, ma) @C# float TCODRandom::getFloat(float min, float max) @Param mersenne In the C and Python versions, the generator handler, returned by the initialization functions. If NULL, the default generator is used. @Param min,max Range of values returned. Each time you call this function, you get a number between (including) min and max @Param mean This is used to set a custom mean, ie, not min+((max-min)/2). It can even be outside of the min-max range. Using a mean will force the use of a weighted (Gaussian) distribution, even if linear is set. @CppEx // default generator TCODRandom * default = TCODRandom::getInstance(); int aRandomIntBetween0And1000 = default->getInt(0,1000); int anotherRandomInt = default->get(0,1000); // another random generator TCODRandom *myRandom = new TCODRandom(); float aRandomFloatBetween0And1000 = myRandom->getFloat(0.0f,1000.0f); float anotherRandomFloat = myRandom->get(0.0f,1000.0f); @CEx // default generator int a_random_int_between_0_and_1000 = TCOD_random_get_float(NULL,0,1000); // another random generator TCOD_random_t my_random = TCOD_random_new(); float a_random_float_between_0_and_1000 = TCOD_random_get_float(my_random,0.0f,1000.0f); @PyEx # default generator a_random_int_between_0_and_1000 = libtcod.random_get_float(0,0,1000) # another random generator my_random = libtcod.random_new() a_random_float_between_0_and_1000 = libtcod.random_get_float(my_random,0.0,1000.0) */ inline float getFloat (float min, float max, float mean = 0.0f) { return (mean <= 0) ? TCOD_random_get_float(data,min,max) : TCOD_random_get_float_mean(data,min,max,mean); } inline float get (float min, float max, float mean = 0.0f) { return (mean <= 0.0f) ? TCOD_random_get_float(data,min,max) : TCOD_random_get_float_mean(data,min,max,mean); } /** @PageName random_use @FuncTitle Getting a double @FuncDesc To get a random double precision floating point number, using either the explicit or simplified API where applicable @Cpp //explicit API: double TCODRandom::getDouble(double min, double max, double mean = 0.0f) //simplified API: double TCODRandom::get(double min, double max, double mean = 0.0f) @C double TCOD_random_get_double(TCOD_random_t mersenne, double min, double max) double TCOD_random_get_double_mean(TCOD_random_t mersenne, double min, double max, double mean) @Py @C# @Param mersenne In the C and Python versions, the generator handler, returned by the initialization functions. If NULL, the default generator is used. @Param min,max Range of values returned. Each time you call this function, you get a number between (including) min and max @Param mean This is used to set a custom mean, ie, not min+((max-min)/2). It can even be outside of the min-max range. Using a mean will force the use of a weighted (Gaussian) distribution, even if linear is set. @CppEx // default generator TCODRandom * default = TCODRandom::getInstance(); int aRandomIntBetween0And1000 = default->getInt(0,1000); int anotherRandomInt = default->get(0,1000); // another random generator TCODRandom *myRandom = new TCODRandom(); float aRandomFloatBetween0And1000 = myRandom->getFloat(0.0f,1000.0f); float anotherRandomFloat = myRandom->get(0.0f,1000.0f); @CEx // default generator int a_random_int_between_0_and_1000 = TCOD_random_get_float(NULL,0,1000); // another random generator TCOD_random_t my_random = TCOD_random_new(); float a_random_float_between_0_and_1000 = TCOD_random_get_float(my_random,0.0f,1000.0f); @PyEx # default generator a_random_int_between_0_and_1000 = libtcod.random_get_float(0,0,1000) # another random generator my_random = libtcod.random_new() a_random_float_between_0_and_1000 = libtcod.random_get_float(my_random,0.0,1000.0) */ inline double getDouble (double min, double max, double mean = 0.0) { return (mean <= 0) ? TCOD_random_get_double(data,min,max) : TCOD_random_get_double_mean(data,min,max,mean); } inline double get (double min, double max, double mean = 0.0f) { return (mean <= 0.0) ? TCOD_random_get_double(data,min,max) : TCOD_random_get_double_mean(data,min,max,mean); } /** @PageName random_use @FuncTitle Saving a RNG state @FuncDesc You can save the state of a generator with : @Cpp TCODRandom *TCODRandom::save() const @C TCOD_random_t TCOD_random_save(TCOD_random_t mersenne) @Py random_save(mersenne) @C# TCODRandom TCODRandom::save() @Param mersenne In the C and Python versions, the generator handler, returned by the initialization functions. If NULL, the default generator is used. */ TCODRandom * save() const; /** @PageName random_use @FuncTitle Restoring a saved state @FuncDesc And restore it later. This makes it possible to get the same series of number several times with a single generator. @Cpp void TCODRandom::restore(const TCODRandom *backup) @C void TCOD_random_restore(TCOD_random_t mersenne, TCOD_random_t backup) @Py random_restore(mersenne, backup) @C# void TCODRandom::restore(TCODRandom backup) @Param mersenne In the C and Python versions, the generator handler, returned by the initialization functions. If NULL, the default generator is used. @CppEx // default generator TCODRandom * default = TCODRandom::getInstance(); // save the state TCODRandom *backup=default->save(); // get a random number (or several) int number1 = default->getInt(0,1000); // restore the state default->restore(backup); // get a random number int number2 = default->getInt(0,1000); // => number1 == number2 @CEx // save default generator state TCOD_random_t backup=TCOD_random_save(NULL); // get a random number int number1 = TCOD_random_get_float(NULL,0,1000); // restore the state TCOD_random_restore(NULL,backup); // get a random number int number2 = TCOD_random_get_float(NULL,0,1000); // number1 == number2 @PyEx # save default generator state backup=libtcod.random_save(0) # get a random number number1 = libtcod.random_get_float(0,0,1000) # restore the state libtcod.random_restore(0,backup) # get a random number number2 = libtcod.random_get_float(0,0,1000) # number1 == number2 */ void restore(const TCODRandom *backup); //dice inline TCOD_dice_t dice (const char * s) { return TCOD_random_dice_new(s); } inline int diceRoll (TCOD_dice_t dice) { return TCOD_random_dice_roll(data,dice); } inline int diceRoll (const char * s) { return TCOD_random_dice_roll(data,TCOD_random_dice_new(s)); } protected : friend class TCODLIB_API TCODNoise; friend class TCODLIB_API TCODHeightMap; friend class TCODLIB_API TCODNamegen; friend class TCODNameGenerator; // Used for SWIG interface, does NOT need TCODLIB_API TCOD_random_t data; }; #endif libtcod-1.6.4+dfsg/include/mersenne_types.h000066400000000000000000000040441321276576200207320ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_RANDOM_TYPES_H #define _TCOD_RANDOM_TYPES_H typedef void *TCOD_random_t; /* dice roll */ typedef struct { int nb_rolls; int nb_faces; float multiplier; float addsub; } TCOD_dice_t; /* PRNG algorithms */ typedef enum { TCOD_RNG_MT, TCOD_RNG_CMWC } TCOD_random_algo_t; typedef enum { TCOD_DISTRIBUTION_LINEAR, TCOD_DISTRIBUTION_GAUSSIAN, TCOD_DISTRIBUTION_GAUSSIAN_RANGE, TCOD_DISTRIBUTION_GAUSSIAN_INVERSE, TCOD_DISTRIBUTION_GAUSSIAN_RANGE_INVERSE } TCOD_distribution_t; #endif /* _TCOD_RANDOM_TYPES_H */ libtcod-1.6.4+dfsg/include/mouse.h000066400000000000000000000040341321276576200170210ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_MOUSE_H #define _TCOD_MOUSE_H #include "libtcod_portability.h" #ifdef TCOD_CONSOLE_SUPPORT #include "mouse_types.h" #ifdef __cplusplus extern "C" { #endif TCODLIB_API void TCOD_mouse_show_cursor(bool visible); TCODLIB_API TCOD_mouse_t TCOD_mouse_get_status(void); TCODLIB_API bool TCOD_mouse_is_cursor_visible(void); TCODLIB_API void TCOD_mouse_move(int x, int y); TCODLIB_API void TCOD_mouse_includes_touch(bool enable); #ifdef __cplusplus } #endif #endif /* TCOD_CONSOLE_SUPPORT */ #endif /* _TCOD_MOUSE_H */ libtcod-1.6.4+dfsg/include/mouse.hpp000066400000000000000000000070141321276576200173620ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_MOUSE_HPP #define _TCOD_MOUSE_HPP #include "mouse.h" #ifdef TCOD_CONSOLE_SUPPORT #include "mouse_types.h" class TCODLIB_API TCODMouse { public : /** @PageName mouse @PageTitle Mouse support @PageCategory Base toolkits @FuncTitle Display and hide the mouse cursor @FuncDesc By default, the mouse cursor in visible in windowed mode, hidden in fullscreen mode. You can change it with: @Cpp static void TCODMouse::showCursor (bool visible) @C void TCOD_mouse_show_cursor (bool visible) @Py mouse_show_cursor (visible) @C# void TCODMouse::showCursor(bool visible) @Param visible If true, this function turns the mouse cursor on. Else it turns the mouse cursor off. */ static void showCursor(bool visible); /** @PageName mouse @FuncTitle Getting the cursor status @FuncDesc You can get the current cursor status (hidden or visible) with: @Cpp static bool TCODMouse::isCursorVisible (void) @C bool TCOD_mouse_is_cursor_visible (void) @Py mouse_is_cursor_visible () @C# bool TCODMouse::isCursorVisible() */ static bool isCursorVisible(); /** @PageName mouse @FuncTitle Setting the mouse cursor's position @FuncDesc You can set the cursor position (in pixel coordinates, where [0,0] is the window's top left corner) with: @Cpp static void TCODMouse::move (int x, int y) @C void TCOD_mouse_move (int x, int y) @Py mouse_move (x, y) @C# void TCODMouse::moveMouse(int x, int y) @Param x,y New coordinates of the mouse cursor in pixels. */ static void move(int x, int y); /** @PageName mouse @FuncTitle Get the last known mouse cursor position @FuncDesc This function is only valid, and only returns updated values, after you have called event-related functions. Whether to check for events, or wait for events. It does not provide the actual mouse position at the time the call is made. @Cpp static TCOD_mouse_t TCODMouse::getStatus () @C void TCOD_mouse_get_status () @Py mouse_get_status () */ static TCOD_mouse_t getStatus(); }; #endif /* TCOD_CONSOLE_SUPPORT */ #endif /* _TCOD_MOUSE_HPP */ libtcod-1.6.4+dfsg/include/mouse_types.h000066400000000000000000000045221321276576200202470ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_MOUSE_TYPES_H #define _TCOD_MOUSE_TYPES_H #include "libtcod_portability.h" #ifdef __cplusplus extern "C" { #endif /* mouse data */ typedef struct { int x,y; /* absolute position */ int dx,dy; /* movement since last update in pixels */ int cx,cy; /* cell coordinates in the root console */ int dcx,dcy; /* movement since last update in console cells */ bool lbutton ; /* left button status */ bool rbutton ; /* right button status */ bool mbutton ; /* middle button status */ bool lbutton_pressed ; /* left button pressed event */ bool rbutton_pressed ; /* right button pressed event */ bool mbutton_pressed ; /* middle button pressed event */ bool wheel_up ; /* wheel up event */ bool wheel_down ; /* wheel down event */ } TCOD_mouse_t; #ifdef __cplusplus } #endif #endif /* _TCOD_MOUSE_TYPES_H */ libtcod-1.6.4+dfsg/include/namegen.h000066400000000000000000000045661321276576200173150ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Mingos' NameGen * This file was written by Dominik "Mingos" Marczuk. */ #ifndef _TCOD_NAMEGEN_H #define _TCOD_NAMEGEN_H #include "libtcod_portability.h" #include "list.h" #include "mersenne.h" #ifdef __cplusplus extern "C" { #endif /* the generator typedef */ typedef void * TCOD_namegen_t; /* parse a file with syllable sets */ TCODLIB_API void TCOD_namegen_parse (const char * filename, TCOD_random_t random); /* generate a name */ TCODLIB_API char * TCOD_namegen_generate (char * name, bool allocate); /* generate a name using a custom generation rule */ TCODLIB_API char * TCOD_namegen_generate_custom (char * name, char * rule, bool allocate); /* retrieve the list of all available syllable set names */ TCODLIB_API TCOD_list_t TCOD_namegen_get_sets (void); /* delete a generator */ TCODLIB_API void TCOD_namegen_destroy (void); #ifdef __cplusplus } #endif #endif libtcod-1.6.4+dfsg/include/namegen.hpp000066400000000000000000000402351321276576200176460ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Mingos' NameGen * This file was written by Dominik "Mingos" Marczuk. */ #ifndef _TCOD_NAMEGEN_HPP #define _TCOD_NAMEGEN_HPP #include "list.hpp" #include "mersenne.hpp" #include "namegen.h" /** @PageName namegen @PageCategory Roguelike toolkits @PageTitle Name generator @PageDesc This tool allows one to generate random names out of custom made syllable sets. */ class TCODLIB_API TCODNamegen { public: /** @PageName namegen_init @PageFather namegen @PageTitle Creating a generator @FuncDesc In order to be able to generate names, the name generator needs to be fed proper data. It will then be ready to generate random names defined in the file(s) it is fed. Syllable set parsing is achieved via the following. Note 1: Each file will be parsed once only. If, for some reason, you would like to parse the same file twice, you will need to destroy the generator first, which will empty the list of parsed files along with erasing all the data retrieved from those files. Note 2: The generator can be fed data multiple times if you have it in separate files. Just make sure the structure names in them aren't duplicated, otherwise they will be silently ignored. Note 3: In the C++ version, you are not obliged to specify the random number generator. If you skip it in the function call, the generator will assume you would like to use an instance of the default generator. @Cpp static void TCODNamegen::parse (const char * filename, TCODRandom * random = NULL) @C void TCOD_namegen_parse (const char * filename, TCOD_random_t random) @Py namegen_parse (filename, random = 0) @C# static void TCODNameGenerator::parse(string filename) static void TCODNameGenerator::parse(string filename, TCODRandom random) @Param filename The file where the desired syllable set is saved, along with its relative parh, for instance, "data/names.txt". @Param random A random number generator object. Use NULL for the default random number generator @CppEx TCODNamegen::parse("data/names.txt",TCODRandom::getInstance()); TCODNamegen::parse("data/names2.txt"); @CEx TCOD_namegen_parse("data/names.txt",TCOD_random_get_instance()); @PyEx libtcod.namegen_parse('data/names.txt') */ static void parse (const char * filename, TCODRandom * random = NULL); /** @PageName namegen_init @FuncTitle Destroying a generator @FuncDesc To release the resources used by a name generator, you may call: This will free all memory used by the generator. In order to generate a name again, you have to parse a file again. @Cpp static void TCODNamegen::destroy (void) @C void TCOD_namegen_destroy (void) @Py namegen_destroy () @C# static void TCODNameGenerator::destroy() */ static void destroy (void); /** @PageName namegen_generate @PageTitle Generating a name @PageFather namegen @FuncTitle Generating a default name @FuncDesc The following will output a random name generated using one of the generation rules specified in the syllable set: Should you choose to allocate memory for the output, you need to remember to deallocate it once you don't need the name anymore using the free() function. This applies to C++ as well (delete won't work - you have to use free()). On the other hand, should you choose not to allocate memory, be aware that subsequent calls will overwrite the previously returned pointer, so make sure to copy the output using strcpy(), strdup() or other means of your choosing. The name you specify needs to be in one of the files the generator has previously parsed (see Creating a generator). If such a name doesn't exist, a warning will be displayed and NULL will be returned. @Cpp static char * TCODNamegen::generate (char * name, bool allocate = false) @C char * TCOD_namegen_generate (char * name, bool allocate) @Py namegen_generate (name, allocate = 0) @C# string TCODNameGenerator::generate (string name) @Param name The structure name you wish to refer to, for instance, "celtic female". For more about how structure names work, please refer to those chapters. @Param allocate Whether memory should be allocated for the output or not. @CppEx TCODNamegen::parse("data/names.txt",TCODRandom::getInstance()); char * myName = TCODNamegen::generate("fantasy female"); @CEx TCOD_namegen_parse("data/names.txt",TCOD_random_get_instance()); char * my_name = TCOD_namegen_generate("Celtic male",false); @PyEx libtcod.namegen_parse('data/names.txt') name = libtcod.namegen_generate('Nordic female') */ static char * generate (char * name, bool allocate = false); /** @PageName namegen_generate @FuncTitle Generating a custom name @FuncDesc It is also possible to generate a name using custom generation rules. This overrides the random choice of a generation rule from the syllable set. Please refer to chapter 16.5 to learn about the name generation rules syntax. @Cpp static char * TCODNamegen::generateCustom (char * name, char * rule, bool allocate = false) @C char * TCOD_namegen_generate_custom (char * name, char * rule, bool allocate) @Py namegen_generate_custom (name, rule, allocate = 0) @C# string TCODNameGenerator::generateCustom (string name, string rule) @Param name The structure name you wish to refer to, for instance, "celtic female". For more about how structure names work, please refer to those chapters. @Param rule The name generation rule. See this chapter for more details. @Param allocate Whether memory should be allocated for the output or not. @CppEx TCODNamegen::parse("data/names.txt",TCODRandom::getInstance()); char * myName = TCODNamegen::generateCustom("Nordic male","$s$e"); @CEx TCOD_namegen_parse("data/names.txt",TCOD_random_get_instance()); char * my_name = TCOD_namegen_generate_custom("Mesopotamian female","$s$e",false); @PyEx libtcod.namegen_parse('data/names.txt') name = libtcod.namegen_generate_custom('Nordic female','$s$e') */ static char * generateCustom (char * name, char * rule, bool allocate = false); /** @PageName namegen_generate @FuncTitle Retrieving available set names @FuncDesc If you wish to check the sylable set names that are currently available, you may call: This will create a list with all the available syllable set names. Remember to delete that list after you don't need it anymore! @Cpp static TCODList TCODNamegen::getSets () @C TCOD_list_t TCOD_namegen_get_sets () @Py namegen_get_sets () @C# static IEnumerable TCODNameGenerator::getSets() */ static TCOD_list_t getSets (void); /** @PageName namegen_file @PageFather namegen @PageTitle Syllable set configuration @PageDesc Configuring the syllable set is vital to obtaining high quality randomly generated names. Please refer to the following subchapters for detailed information: */ /** @PageName namegen_file_1 @PageFather namegen_file @PageTitle Syllable set basic structure @PageDesc The syllable sets need to be written in one or more text files that will be opened and parsed by the generator. The data uses a standard TCODParser file and data should be inserted according to the general rules of creating a configuration file. For more information, please refer to The libtcod config file format. The structure type that's defined in the generator is "name". This structure type must also be accompanied by a structure name. It will be used for identification purposes in the generator. For instance, if you use a structure name "fantasy female", you will be able to access this syllable set by creating a generator using "fantasy female" syllables. In the initialisation function, this is the "const char * name" argument. The structure contains different members, all of which must be of TCOD_TYPE_STRING type. The tokens inside the strings, be them phonemes or syllables, form a single string, but are separated with separator characters. Characters used for token separation are all characters that are not Latin upper- or lowercase characters, dashes or apostrophes. A comma, a space or a comma+space are all perfectly valid, human-readable separators. In order to use a character inside a string that would normally be considered a separator, precede it with a slash (eg. "/:", "/.", "/!", etc.). An exception to this rule is the space character, which can also be achieved by using an underscore (eg. "the_Great"). The structure members that may thus be defined are:

phonemesVocals phonemesConsonants syllablesPre syllablesStart syllablesMiddle syllablesEnd syllablesPost

All of those strings are considered optional. However, if you don't define a string, but reference it in the name generation rules, you will see a warning displayed on stderr about missing data. */ /** @PageName namegen_file_2 @PageFather namegen_file @PageTitle Illegal strings @PageDesc Another optional property is

illegal

This property contains strings that are considered illegal and thus not desired in your names. Should a generated name contain any of the tokens specified in this string, it will be discarded and replaced by a new one. Illegal strings may be as short as single characters or as long as entire names. However, it is best to create a syllable set that generates very few names that sound bad. Otherwise, the illegal list might become very long. Be aware that the generator will automatically correct or reject certain words, so you don't need to place every undesired possibility in this string. The generator will correct the following: * leading spaces ("_NAME") * ending spaces ("NAME_") * double spaces ("NAME1__NAME2") It will generate a new name in the following cases: * triple characters ("Raaagnar") * two-character adjacent repetitions ("Bobofur" is wrong, but "Bombofur" is OK) * three-character (or more) repetitions, whether adjacent or not ("Bombombur", "Dagbjoerdag", "Gwaerdygwaern") Remember that all of this is case-insensitive, so you don't need to care about uppercase/lowercase distinction in your illegal strings. */ /** @PageName namegen_file_3 @PageFather namegen_file @PageTitle Rules @PageDesc There's one last string that's contained within the structure:

rules

It is mandatory, so not defining it will trigger an error. It defines how the generator should join the supplied data in order to generate a name. This string uses a syntax of its own, which is also used when specifying a rule when generating a custom name (see chapter 16.2). The rules are parsed pretty much the same way as all other strings, so all rules regarding separators and special characters apply as well. However, you can additionally use a set of wildcards and frequency markers. Each wildcard is preceded by the dollar sign ('$'), while frequency markers are preceded by the per cent sign ('%'). Here's the complete wildcard list:
WildcardExampleDescription
$[INT]P$P, $25PUse a random Pre syllable.
The optional integer value denotes the per cent chance of adding the syllable.
$[INT]s$s, $25sUse a random Start syllable.
$[INT]m$m, $25mUse a random Middle syllable.
$[INT]e$e, $25eUse a random End syllable.
$[INT]p$p, $25pUse a random Post syllable.
$[INT]v$v, $25vUse a random vocal.
$[INT]c$c, $25cUse a random consonant.
$[INT]?$?, $25?Use a random phoneme (vocal or consonant).
%INT%50, %25Frequency marker. Denotes the per cent chance for the rule to be accepted if it's picked.
If the rule is not accepted, another roll is made to choose a name generation rule.
It's used to reduce the frequency a given rule is chosen with.
This marker may only appear at the beginning of a rule.
*/ /** @PageName namegen_file_4 @PageFather namegen_file @PageTitle Example structure @PageDesc Consider this example structure. It does not contain syllables, but rather full names.

name "king" { syllablesStart = "Alexander, Augustus, Casimir, Henry, John, Louis, Sigismund," "Stanislao, Stephen, Wenceslaus" syllablesMiddle = "I, II, III, IV, V" syllablesEnd = "Bathory, Herman, Jogaila, Lambert, of_Bohemia, of_France," "of_Hungary, of_Masovia, of_Poland, of_Valois, of_Varna, Probus," "Spindleshanks, Tanglefoot, the_Bearded, the_Black, the_Bold, the_Brave," "the_Chaste, the_Curly, the_Elbow-high, the_Exile, the_Great," "the_Jagiellonian, the_Just, the_Old, the_Pious, the_Restorer, the_Saxon," "the_Strong, the_Wheelwright, the_White, Vasa, Wrymouth" rules = "%50$s, $s_$m, $s_$50m_$e" }

The above structure only uses three syllable lists and has three different rules. Let's analyse them one by one. %50$s - this will simply output a random Start syllable, but this rule is not intended to be picked with the same frequency as the others, so the frequency marker at the beginning ("%50") ensures that 50% of the time this syllable will be rejected and a different one will be picked. $s_$m - this will output a Start syllable and a Middle syllable, separated with a space. $s_$50m_$e - This will output a Start syllable, followed by a Middle syllable, followed by an End sylable, all separated with spaces. However, the Middle syllable has only 50% chance of appearing at all, so 50% of the time the rule will actually produce a Start syllable followed directly by an End syllable, separated with a space. As you may have noticed, the third rule may produce a double space if the Middle syllable is not chosen. You do not have to worry about such cases, as the generator will automatically reduce all double spaces to single spaces, and leading/ending spaces will be removed completely. Output from this example set would contain kings' names based on the names of real monarchs of Poland. Have a look at the sample:

Alexander IV Alexander Sigismund Stanislao V Stanislao Henry I of Poland Augustus V Stanislao I the Pious Sigismund IV the Brave John the Great Henry the Old John the Bold Stanislao II the Saxon Wenceslaus of France John Probus Louis V Wenceslaus Lambert Stanislao Spindleshanks Henry Herman Alexander the Old Louis V the Curly Wenceslaus II Augustus IV Alexander V Augustus Probus

*/ }; #endif libtcod-1.6.4+dfsg/include/noise.h000066400000000000000000000053771321276576200170210ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_PERLIN_H #define _TCOD_PERLIN_H #include "libtcod_portability.h" #include "mersenne_types.h" #ifdef __cplusplus extern "C" { #endif typedef void *TCOD_noise_t; typedef enum { TCOD_NOISE_PERLIN = 1, TCOD_NOISE_SIMPLEX = 2, TCOD_NOISE_WAVELET = 4, TCOD_NOISE_DEFAULT = 0 } TCOD_noise_type_t; #include "noise_defaults.h" /* create a new noise object */ TCODLIB_API TCOD_noise_t TCOD_noise_new(int dimensions, float hurst, float lacunarity, TCOD_random_t random); /* simplified API */ TCODLIB_API void TCOD_noise_set_type (TCOD_noise_t noise, TCOD_noise_type_t type); TCODLIB_API float TCOD_noise_get_ex (TCOD_noise_t noise, float *f, TCOD_noise_type_t type); TCODLIB_API float TCOD_noise_get_fbm_ex (TCOD_noise_t noise, float *f, float octaves, TCOD_noise_type_t type); TCODLIB_API float TCOD_noise_get_turbulence_ex (TCOD_noise_t noise, float *f, float octaves, TCOD_noise_type_t type); TCODLIB_API float TCOD_noise_get (TCOD_noise_t noise, float *f); TCODLIB_API float TCOD_noise_get_fbm (TCOD_noise_t noise, float *f, float octaves); TCODLIB_API float TCOD_noise_get_turbulence (TCOD_noise_t noise, float *f, float octaves); /* delete the noise object */ TCODLIB_API void TCOD_noise_delete(TCOD_noise_t noise); #ifdef __cplusplus } #endif #endif libtcod-1.6.4+dfsg/include/noise.hpp000066400000000000000000000365221321276576200173550ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_PERLIN_HPP #define _TCOD_PERLIN_HPP #include "mersenne.hpp" #include "noise.h" #include "noise_defaults.h" /** @PageName noise @PageCategory Base toolkits @PageTitle Noise generator @PageDesc This toolkit provides several functions to generate Perlin noise and other derived noises. It can handle noise functions from 1 to 4 dimensions. @FuncDesc Usage example: 1D noise : the variation of a torch intensity 2D fbm : heightfield generation or clouds 3D fbm : animated smoke If you don't know what is Perlin noise and derived functions, or what is the influence of the different fractal parameters, check the Perlin noise sample included with the library.
Simplex noise, fbm, turbulence
Perlin noise, fbm, turbulence
Wavelet noise, fbm, turbulence
Noise functions relative times
For example, in 4D, Perlin noise is 17 times slower than simplex noise.
1D2D3D4D
simplex1111
Perlin1.34517
wavelet533214X
*/ class TCODLIB_API TCODNoise { public : /** @PageName noise_init @PageFather noise @PageTitle Creating a noise generator @FuncDesc Those functions initialize a noise generator from a number of dimensions (from 1 to 4), some fractal parameters and a random number generator. The C++ version provides several constructors. When the hurst and lacunarity parameters are omitted, default values (TCOD_NOISE_DEFAULT_HURST = 0.5f and TCOD_NOISE_DEFAULT_LACUNARITY = 2.0f) are used. @Cpp TCODNoise::TCODNoise(int dimensions, TCOD_noise_type_t type = TCOD_NOISE_DEFAULT) TCODNoise::TCODNoise(int dimensions, TCODRandom *random, TCOD_noise_type_t type = TCOD_NOISE_DEFAULT) TCODNoise::TCODNoise(int dimensions, float hurst, float lacunarity, TCOD_noise_type_t type = TCOD_NOISE_DEFAULT) TCODNoise::TCODNoise(int dimensions, float hurst, float lacunarity, TCODRandom *random, TCOD_noise_type_t type = TCOD_NOISE_DEFAULT) @C TCOD_noise_t TCOD_noise_new(int dimensions, float hurst, float lacunarity, TCOD_random_t random) @Py noise_new(dimensions, hurst=TCOD_NOISE_DEFAULT_HURST, lacunarity=TCOD_NOISE_DEFAULT_LACUNARITY, random=0) @C# TCODNoise::TCODNoise(int dimensions) TCODNoise::TCODNoise(int dimensions, TCODRandom random) TCODNoise::TCODNoise(int dimensions, float hurst, float lacunarity) TCODNoise::TCODNoise(int dimensions, float hurst, float lacunarity, TCODRandom random) @Param dimensions From 1 to 4. @Param hurst For fractional brownian motion and turbulence, the fractal Hurst exponent. You can use the default value TCOD_NOISE_DEFAULT_HURST = 0.5f. @Param lacunarity For fractional brownian motion and turbulence, the fractal lacunarity. You can use the default value TCOD_NOISE_DEFAULT_LACUNARITY = 2.0f. @Param random A random number generator obtained with the Mersenne twister toolkit or NULL to use the default random number generator. @CppEx // 1 dimension generator TCODNoise * noise1d = new TCODNoise(1); // 2D noise with a predefined random number generator TCODRandom *myRandom = new TCODRandom(); TCODNoise *noise2d = new TCODNoise(2,myRandom); // a 3D noise generator with a specific fractal parameters TCODNoise *noise3d = new TCODNoise(3,0.7f,1.4f); @CEx // 1 dimension generator TCOD_noise_t noise1d = TCOD_noise_new(1,TCOD_NOISE_DEFAULT_HURST, TCOD_NOISE_DEFAULT_LACUNARITY,NULL); // 2D noise with a predefined random number generator TCOD_random_t my_random = TCOD_random_new(); TCOD_noise_t noise2d = TCOD_noise_new(2,TCOD_NOISE_DEFAULT_HURST, TCOD_NOISE_DEFAULT_LACUNARITY,my_random); // a 3D noise generator with a specific fractal parameters TCOD_noise_t noise3d = TCOD_noise_new(3,0.7f, 1.4f,NULL); @PyEx # 1 dimension generator noise1d = libtcod.noise_new(1) # 2D noise with a predefined random number generator my_random = libtcod.random_new(); noise2d = libtcod.noise_new(2,libtcod.NOISE_DEFAULT_HURST, libtcod.NOISE_DEFAULT_LACUNARITY,my_random) # a 3D noise generator with a specific fractal parameters noise3d = libtcod.noise_new(3, 0.7, 1.4) */ TCODNoise(int dimensions, TCOD_noise_type_t type = TCOD_NOISE_DEFAULT); TCODNoise(int dimensions, TCODRandom *random, TCOD_noise_type_t type = TCOD_NOISE_DEFAULT); TCODNoise(int dimensions, float hurst, float lacunarity, TCOD_noise_type_t type = TCOD_NOISE_DEFAULT); TCODNoise(int dimensions, float hurst, float lacunarity, TCODRandom *random, TCOD_noise_type_t type = TCOD_NOISE_DEFAULT); /** @PageName noise_init @FuncDesc To release resources used by a generator, use those functions : @Cpp TCODNoise::~TCODNoise() @C void TCOD_noise_delete(TCOD_noise_t noise) @Py noise_delete(noise) @C# void TCODNoise::Dispose() @Param noise In the C and Python versions, the generator handler, returned by the initialization function. @CppEx // create a generator TCODNoise *noise = new TCODNoise(2); // use it ... // destroy it delete noise; @CEx // create a generator TCOD_noise_t noise = TCOD_noise_new(2,TCOD_NOISE_DEFAULT_HURST, TCOD_NOISE_DEFAUT_LACUNARITY, NULL); // use it ... // destroy it TCOD_noise_delete(noise); @PyEx # create a generator noise = libtcod.noise_new(2,litbcod.NOISE_DEFAULT_HURST, litbcod.NOISE_DEFAUT_LACUNARITY, 0) # use it ... # destroy it litbcod.noise_delete(noise) */ virtual ~TCODNoise(); /** @PageName noise_setType @PageFather noise @PageTitle Choosing a noise type @FuncTitle Choosing a noise type @FuncDesc Use this function to define the default algorithm used by the noise functions. The default algorithm is simplex. It's much faster than Perlin, especially in 4 dimensions. It has a better contrast too. @Cpp void TCODNoise::setType(TCOD_noise_type_t type) @C void TCOD_noise_set_type(TCOD_noise_t noise, TCOD_noise_type_t type) @Py noise_set_type(noise, type) @C# void TCODNoise::setType(type) @Param noise In the C version, the generator handler, returned by the initialization function. @Param type The algorithm to use, either TCOD_NOISE_SIMPLEX, TCOD_NOISE_PERLIN or TCOD_NOISE_WAVELET. @CppEx TCODNoise * noise1d = new TCODNoise(1); noise1d->setType(TCOD_NOISE_PERLIN); @CEx TCOD_noise_t noise1d = TCOD_noise_new(1,TCOD_NOISE_DEFAULT_HURST, TCOD_NOISE_DEFAULT_LACUNARITY,NULL); TCOD_noise_set_type(noise1d,TCOD_NOISE_PERLIN); @PyEx noise1d = libtcod.noise_new(1) libtcod.noise_set_type(noise1d,libtcod.NOISE_PERLIN) */ void setType (TCOD_noise_type_t type); /** @PageName noise_get @PageFather noise @PageTitle Getting flat noise @FuncDesc This function returns the noise function value between -1.0 and 1.0 at given coordinates. @Cpp float TCODNoise::get(float *f, TCOD_noise_type_t type = TCOD_NOISE_DEFAULT) @C float TCOD_noise_get(TCOD_noise_t noise, float *f) float TCOD_noise_get_ex(TCOD_noise_t noise, float *f, TCOD_noise_type_t type) @Py noise_get(noise, f, type=NOISE_DEFAULT) @C# float TCODNoise::get(float[] f, type=NoiseDefault) @Param noise In the C version, the generator handler, returned by the initialization function. @Param f An array of coordinates, depending on the generator dimensions (between 1 and 4). The same array of coordinates will always return the same value. @Param type The algorithm to use. If not defined, use the default one (set with setType or simplex if not set) @CppEx // 1d noise TCODNoise * noise1d = new TCODNoise(1); float p=0.5f; // get a 1d simplex value float value = noise1d->get(&p); // 2d noise TCODNoise * noise2d = new TCODNoise(2); float p[2]={0.5f,0.7f}; // get a 2D Perlin value float value = noise2d->get(p, TCOD_NOISE_PERLIN); @CEx // 1d noise TCOD_noise_t noise1d = TCOD_noise_new(1,TCOD_NOISE_DEFAULT_HURST, TCOD_NOISE_DEFAULT_LACUNARITY,NULL); float p=0.5f; // get a 1d simplex value float value = TCOD_noise_get(noise1d,&p); // 2d noise TCOD_noise_t noise2d = TCOD_noise_new(2,TCOD_NOISE_DEFAULT_HURST, TCOD_NOISE_DEFAULT_LACUNARITY,NULL); float p[2]={0.5f,0.7f}; // get a 2d perlin value float value = TCOD_noise_get_ex(noise2d,p,TCOD_NOISE_PERLIN); @PyEx # 1d noise noise1d = libtcod.noise_new(1) # get a 1d simplex value value = libtcod.noise_get(noise1d,[0.5]) # 2d noise noise2d = libtcod.noise_new(2) # get a 2d perlin value value = libtcod.noise_get(noise2d,[0.5,0.7], libtcod.NOISE_PERLIN) */ float get(float *f, TCOD_noise_type_t type = TCOD_NOISE_DEFAULT); /** @PageName noise_get_fbm @PageFather noise @PageTitle Getting fbm noise @FuncDesc This function returns the fbm function value between -1.0 and 1.0 at given coordinates, using fractal hurst and lacunarity defined when the generator has been created. @Cpp float TCODNoise::getFbm(float *f, float octaves, TCOD_noise_type_t type = TCOD_NOISE_DEFAULT) @C float TCOD_noise_get_fbm(TCOD_noise_t noise, float *f, float octaves) float TCOD_noise_get_fbm(TCOD_noise_t noise, float *f, float octaves, TCOD_noise_type_t type) @Py noise_get_fbm(noise, f, octaves, type=NOISE_DEFAULT) @C# float TCODNoise::getBrownianMotion(float[] f, float octaves, type=NoiseDefault) @Param noise In the C version, the generator handler, returned by the initialization function. @Param f An array of coordinates, depending on the generator dimensions (between 1 and 4). The same array of coordinates will always return the same value. @Param octaves Number of iterations. Must be < TCOD_NOISE_MAX_OCTAVES = 128 @Param type The algorithm to use. If not defined, use the default one (set with setType or simplex if not set) @CppEx // 1d fbm TCODNoise * noise1d = new TCODNoise(1); float p=0.5f; // get a 1d simplex fbm float value = noise1d->getFbm(&p,32.0f); // 2d fbm TCODNoise * noise2d = new TCODNoise(2); float p[2]={0.5f,0.7f}; // get a 2d perlin fbm float value = noise2d->getFbm(p,32.0f, TCOD_NOISE_PERLIN); @CEx // 1d fbm TCOD_noise_t noise1d = TCOD_noise_new(1,TCOD_NOISE_DEFAULT_HURST, TCOD_NOISE_DEFAULT_LACUNARITY,NULL); float p=0.5f; // get a 1d simplex fbm float value = TCOD_noise_get_fbm(noise1d,&p,32.0f); // 2d fbm TCOD_noise_t noise2d = TCOD_noise_new(2,TCOD_NOISE_DEFAULT_HURST, TCOD_NOISE_DEFAULT_LACUNARITY,NULL); float p[2]={0.5f,0.7f}; // get a 2d perlin fbm float value = TCOD_noise_get_fbm_ex(noise2d,p,32.0f,TCOD_NOISE_PERLIN); @PyEx # 1d noise noise1d = libtcod.noise_new(1) # 1d simplex fbm value = libtcod.noise_get_fbm(noise1d,[0.5],32.0) # 2d noise noise2d = libtcod.noise_new(2) # 2d perlin fbm value = libtcod.noise_get_fbm(noise2d,[0.5,0.7],32.0, libtcod.NOISE_PERLIN) */ float getFbm(float *f, float octaves, TCOD_noise_type_t type = TCOD_NOISE_DEFAULT); /** @PageName noise_get_turbulence @PageFather noise @PageTitle Getting turbulence @FuncDesc This function returns the turbulence function value between -1.0 and 1.0 at given coordinates, using fractal hurst and lacunarity defined when the generator has been created. @Cpp float TCODNoise::getTurbulence(float *f, float octaves, TCOD_noise_type_t type = TCOD_NOISE_DEFAULT) @C float TCOD_noise_get_turbulence(TCOD_noise_t noise, float *f, float octaves) float TCOD_noise_get_turbulence_ex(TCOD_noise_t noise, float *f, float octaves, TCOD_noise_type_t) @Py noise_get_turbulence(noise, f, octaves, type=NOISE_DEFAULT) @C# float TCODNoise::getTurbulence(float[] f, float octaves, type=NoiseDefault) @Param noise In the C version, the generator handler, returned by the initialization function. @Param f An array of coordinates, depending on the generator dimensions (between 1 and 4). The same array of coordinates will always return the same value. @Param octaves Number of iterations. Must be < TCOD_NOISE_MAX_OCTAVES = 128 @CppEx // 1d fbm TCODNoise * noise1d = new TCODNoise(1); float p=0.5f; // a 1d simplex turbulence float value = noise1d->getTurbulence(&p,32.0f); // 2d fbm TCODNoise * noise2d = new TCODNoise(2); float p[2]={0.5f,0.7f}; // a 2d perlin turbulence float value = noise2d->getTurbulence(p,32.0f, TCOD_NOISE_PERLIN); @CEx // 1d fbm TCOD_noise_t noise1d = TCOD_noise_new(1,TCOD_NOISE_DEFAULT_HURST, TCOD_NOISE_DEFAULT_LACUNARITY,NULL); float p=0.5f; // a 1d simplex turbulence float value = TCOD_noise_get_turbulence(noise1d,&p,32.0f); // 2d fbm TCOD_noise_t noise2d = TCOD_noise_new(2,TCOD_NOISE_DEFAULT_HURST, TCOD_NOISE_DEFAULT_LACUNARITY,NULL); float p[2]={0.5f,0.7f}; // a 2d perlin turbulence float value = TCOD_noise_get_turbulence_ex(noise2d,p,32.0f, TCOD_NOISE_PERLIN); @PyEx # 1d noise noise1d = libtcod.noise_new(1) # 1d simplex turbulence value = libtcod.noise_get_turbulence(noise1d,[0.5],32.0) # 2d noise noise2d = libtcod.noise_new(2) # 2d perlin turbulence value = libtcod.noise_get_turbulence(noise2d,[0.5,0.7],32.0,libtcod.NOISE_PERLIN) */ float getTurbulence(float *f, float octaves, TCOD_noise_type_t type = TCOD_NOISE_DEFAULT); protected : friend class TCODLIB_API TCODHeightMap; TCOD_noise_t data; }; #endif libtcod-1.6.4+dfsg/include/noise_defaults.h000066400000000000000000000004021321276576200206700ustar00rootroot00000000000000#ifndef _TCOD_NOISE_DEFAULTS #define _TCOD_NOISE_DEFAULTS #define TCOD_NOISE_MAX_OCTAVES 128 #define TCOD_NOISE_MAX_DIMENSIONS 4 #define TCOD_NOISE_DEFAULT_HURST 0.5f #define TCOD_NOISE_DEFAULT_LACUNARITY 2.0f #endif /* _TCOD_NOISE_DEFAULTS */ libtcod-1.6.4+dfsg/include/parser.h000066400000000000000000000163431321276576200171730ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_PARSER_H #define _TCOD_PARSER_H #include "libtcod_portability.h" #include "color.h" #include "list.h" #include "lex.h" #include "mersenne.h" #ifdef __cplusplus extern "C" { #endif /* generic type */ typedef enum { TCOD_TYPE_NONE, TCOD_TYPE_BOOL, TCOD_TYPE_CHAR, TCOD_TYPE_INT, TCOD_TYPE_FLOAT, TCOD_TYPE_STRING, TCOD_TYPE_COLOR, TCOD_TYPE_DICE, TCOD_TYPE_VALUELIST00, TCOD_TYPE_VALUELIST01, TCOD_TYPE_VALUELIST02, TCOD_TYPE_VALUELIST03, TCOD_TYPE_VALUELIST04, TCOD_TYPE_VALUELIST05, TCOD_TYPE_VALUELIST06, TCOD_TYPE_VALUELIST07, TCOD_TYPE_VALUELIST08, TCOD_TYPE_VALUELIST09, TCOD_TYPE_VALUELIST10, TCOD_TYPE_VALUELIST11, TCOD_TYPE_VALUELIST12, TCOD_TYPE_VALUELIST13, TCOD_TYPE_VALUELIST14, TCOD_TYPE_VALUELIST15, TCOD_TYPE_CUSTOM00, TCOD_TYPE_CUSTOM01, TCOD_TYPE_CUSTOM02, TCOD_TYPE_CUSTOM03, TCOD_TYPE_CUSTOM04, TCOD_TYPE_CUSTOM05, TCOD_TYPE_CUSTOM06, TCOD_TYPE_CUSTOM07, TCOD_TYPE_CUSTOM08, TCOD_TYPE_CUSTOM09, TCOD_TYPE_CUSTOM10, TCOD_TYPE_CUSTOM11, TCOD_TYPE_CUSTOM12, TCOD_TYPE_CUSTOM13, TCOD_TYPE_CUSTOM14, TCOD_TYPE_CUSTOM15, TCOD_TYPE_LIST=1024 } TCOD_value_type_t; /* generic value */ typedef union { bool b; char c; int32_t i; float f; char *s; TCOD_color_t col; TCOD_dice_t dice; TCOD_list_t list; void *custom; } TCOD_value_t; /* parser structures */ typedef void *TCOD_parser_struct_t; TCODLIB_API const char *TCOD_struct_get_name(TCOD_parser_struct_t def); TCODLIB_API void TCOD_struct_add_property(TCOD_parser_struct_t def, const char *name,TCOD_value_type_t type, bool mandatory); TCODLIB_API void TCOD_struct_add_list_property(TCOD_parser_struct_t def, const char *name,TCOD_value_type_t type, bool mandatory); TCODLIB_API void TCOD_struct_add_value_list(TCOD_parser_struct_t def,const char *name, const char **value_list, bool mandatory); TCODLIB_API void TCOD_struct_add_value_list_sized(TCOD_parser_struct_t def,const char *name, const char **value_list, int size, bool mandatory); TCODLIB_API void TCOD_struct_add_flag(TCOD_parser_struct_t def,const char *propname); TCODLIB_API void TCOD_struct_add_structure(TCOD_parser_struct_t def,TCOD_parser_struct_t sub_structure); TCODLIB_API bool TCOD_struct_is_mandatory(TCOD_parser_struct_t def,const char *propname); TCODLIB_API TCOD_value_type_t TCOD_struct_get_type(TCOD_parser_struct_t def, const char *propname); /* parser listener */ typedef struct { bool (*new_struct)(TCOD_parser_struct_t str,const char *name); bool (*new_flag)(const char *name); bool (*new_property)(const char *propname, TCOD_value_type_t type, TCOD_value_t value); bool (*end_struct)(TCOD_parser_struct_t str, const char *name); void (*error)(const char *msg); } TCOD_parser_listener_t; /* a custom type parser */ typedef TCOD_value_t (*TCOD_parser_custom_t)(TCOD_lex_t *lex, TCOD_parser_listener_t *listener, TCOD_parser_struct_t str, char *propname); /* the parser */ typedef void *TCOD_parser_t; TCODLIB_API TCOD_parser_t TCOD_parser_new(void); TCODLIB_API TCOD_parser_struct_t TCOD_parser_new_struct(TCOD_parser_t parser, char *name); TCODLIB_API TCOD_value_type_t TCOD_parser_new_custom_type(TCOD_parser_t parser,TCOD_parser_custom_t custom_type_parser); TCODLIB_API void TCOD_parser_run(TCOD_parser_t parser, const char *filename, TCOD_parser_listener_t *listener); TCODLIB_API void TCOD_parser_delete(TCOD_parser_t parser); /* error during parsing. can be called by the parser listener */ TCODLIB_API void TCOD_parser_error(const char *msg, ...); /* default parser listener */ TCODLIB_API bool TCOD_parser_has_property(TCOD_parser_t parser, const char *name); TCODLIB_API bool TCOD_parser_get_bool_property(TCOD_parser_t parser, const char *name); TCODLIB_API int TCOD_parser_get_char_property(TCOD_parser_t parser, const char *name); TCODLIB_API int TCOD_parser_get_int_property(TCOD_parser_t parser, const char *name); TCODLIB_API float TCOD_parser_get_float_property(TCOD_parser_t parser, const char *name); TCODLIB_API const char * TCOD_parser_get_string_property(TCOD_parser_t parser, const char *name); TCODLIB_API TCOD_color_t TCOD_parser_get_color_property(TCOD_parser_t parser, const char *name); TCODLIB_API TCOD_dice_t TCOD_parser_get_dice_property(TCOD_parser_t parser, const char *name); TCODLIB_API void TCOD_parser_get_dice_property_py(TCOD_parser_t parser, const char *name, TCOD_dice_t *dice); TCODLIB_API void * TCOD_parser_get_custom_property(TCOD_parser_t parser, const char *name); TCODLIB_API TCOD_list_t TCOD_parser_get_list_property(TCOD_parser_t parser, const char *name, TCOD_value_type_t type); /* parser internals (may be used by custom type parsers) */ /* parser structures */ typedef struct { char *name; /* entity type name */ /* list of flags */ TCOD_list_t flags; /* list of properties (name, type, mandatory) */ TCOD_list_t props; /* list of value lists */ TCOD_list_t lists; /* list of sub-structures */ TCOD_list_t structs; } TCOD_struct_int_t; /* the parser */ typedef struct { /* list of structures */ TCOD_list_t structs; /* list of custom type parsers */ TCOD_parser_custom_t customs[16]; /* fatal error occurred */ bool fatal; /* list of properties if default listener is used */ TCOD_list_t props; } TCOD_parser_int_t; TCODLIB_API TCOD_value_t TCOD_parse_bool_value(void); TCODLIB_API TCOD_value_t TCOD_parse_char_value(void); TCODLIB_API TCOD_value_t TCOD_parse_integer_value(void); TCODLIB_API TCOD_value_t TCOD_parse_float_value(void); TCODLIB_API TCOD_value_t TCOD_parse_string_value(void); TCODLIB_API TCOD_value_t TCOD_parse_color_value(void); TCODLIB_API TCOD_value_t TCOD_parse_dice_value(void); TCODLIB_API TCOD_value_t TCOD_parse_value_list_value(TCOD_struct_int_t *def,int listnum); TCODLIB_API TCOD_value_t TCOD_parse_property_value(TCOD_parser_int_t *parser, TCOD_parser_struct_t def, char *propname, bool list); #ifdef __cplusplus } #endif #endif libtcod-1.6.4+dfsg/include/parser.hpp000066400000000000000000001006111321276576200175230ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_PARSER_HPP #define _TCOD_PARSER_HPP #include "color.hpp" #include "list.hpp" #include "parser.h" /** @PageName parser @PageTitle File parser @PageCategory Base toolkits @PageDesc This toolkit provides an easy way to parse complex text configuration files. It has two main advantages compared to a standard XML SAX parser: * The configuration file format is more human readable than XML * The parser knows some data types that it automatically converts to C variables (see Standard data types) */ /** @PageName parser_format @PageFather parser @PageTitle The libtcod config file format @FuncTitle Comments @FuncDesc Your file can contain single line or multi-line comments :
// This is a single line comment
/*
   This is a
   multi-line comment
*/
Multi-line comments can be nested :
/*
   This is a
   multi-line comment containing another
   /*
    multi-line
    comment
   */
*/
The parser is not sensible to space characters, tabulations or carriage return except inside strings. */ /** @PageName parser_format @FuncTitle Structures @FuncDesc The libtcod config file format is basically a list of structures. A structure has a type, an optional name and contains properties. The type of the structure defines which properties are allowed / mandatory.
item_type "blade" {            // structure's type : 'item_type'. structure's name : 'blade'
	cost=300                   // an integer property
	weight=3.5                 // a float property
	deal_damage=true           // a boolean property
	damages="3d6+2"            // a dice property
	col="#FF0000"              // a color property, using #RRGGBB syntax
	damaged_color="128,96,96"  // another color property, using rrr,ggg,bbb syntax
	damage_type="slash"        // a string property
	description="This is a long"
	            "description." // a multi-line string property
	abstract                   // a flag (simplified boolean property)
        intList= [ 1,2,3 ]         // a list of int values
        floatList= [ 1.0,2,3.5 ]   // a list of float values
        stringList= [ "string1","string2","string3" ]         // a list of string values
}
A structure can also contain other structures either of the same type, or structures of another type :
item_type "blade" {
	item_type "one-handed blades" {
		// the item_type "blade" contains another item_type named "one-handed blades"
	}
	item_type "two-handed blades" {
		// the item_type "blade" contains another item_type named "two-handed blades"
	}
	feature "damage" {
		// the item_type "blade" contains another structure, type "feature", name "damage"
	}
}
Sometimes, you don't know the list of properties at compile-time. Fortunately, since libtcod 1.5.1, you can add auto-declaring properties in the file, using one of the type keywords :
item_type "blade" {
	bool deal_damage=true
	char character='D'
	int cost=300
	float weight=3.5
	string damage_type="slash"
	color col="#FF0000"
	dice damages="3d6+2"
	int[] intList= [ 1,2,3 ]
	float[] floatList= [ 1.0,2,3.5 ]
	string[] stringList= [ "string1","string2","string3" ]
}
The properties declared with this syntax were not previously declared for the structure item_type. But since the type is specified, the parser won't reject them. Instead, it will add the property declaration to the structure dynamically (when it parses the file). You can also dynamically create new structures and sub-structures with the struct keyword :
item_type "blade" {
    struct component {
	    string name="blade"
		float weight=1.0
	}
}
With this syntax, you don't need to declare the "component" structure at all in the parser. It will be dynamically registered as the file is parsed. */ class TCODLIB_API TCODParser; class TCODLIB_API TCODParserStruct; class TCODLIB_API ITCODParserListener; class TCODLIB_API TCODParser { public : /** @PageName parser_str @PageTitle Defining the file syntax @PageFather parser @FuncTitle Creating a parser @FuncDesc Use this function to create a generic parser. Then you'll specialize this parser by defining the structures it can read. @Cpp TCODParser::TCODParser() @C TCOD_parser_t TCOD_parser_new() @Py parser_new() */ TCODParser(); /** @PageName parser_str @FuncTitle Registering a new structure type @Cpp TCODParserStruct *TCODParser::newStructure(const char *name) @C TCOD_parser_struct_t TCOD_parser_new_struct(TCOD_parser_t parser, char *name) @Py parser_new_struct(parser, name) @Param parser In the C version, the parser handler, returned by TCOD_parser_new. @Param name The name of the structure type (in the example, this would be "item_type"). @CppEx TCODParser parser(); TCODParserStruct *itemTypeStruct = parser.newStructrue("item_type"); @CEx TCOD_parser_t parser = TCOD_parser_new(); TCOD_parser_struct_t item_type_struct = TCOD_parser_new_struct(parser, "item_type"); @PyEx parser=libtcod.parser_new() item_type_struct = libtcod.parser_new_struct(parser, "item_type") */ TCODParserStruct *newStructure(const char *name); // register a new custom type TCOD_value_type_t newCustomType(TCOD_parser_custom_t custom_type_parser); /** @PageName parser_run @PageFather parser @PageTitle Running the parser @FuncTitle Running the parser @FuncDesc Once you defined all the structure types and created your listener, you can start the actual parsing of the file : @Cpp void TCODParser::run(const char *filename, ITCODParserListener *listener = NULL) @C void TCOD_parser_run(TCOD_parser_t parser, const char *filename, TCOD_parser_listener_t *listener) @Py parser_run(parser, filename, listener=0) @Param parser In the C version, the parser handler, returned by TCOD_parser_new. @Param filename The name of the text file to parse, absolute or relative to current directory. @Param listener The listener containing the callbacks. Use NULL for the default listener @Cpp myParser.run("config.txt",new MyListener()); @C TCOD_parser_run(my_parser,"config.txt", my_listener); @Py libtcod.parser_run(my_parser,"config.txt", MyListener()) */ void run(const char *filename, ITCODParserListener *listener = NULL); /** @PageName parser_run @FuncTitle Destroying the parser @FuncDesc Once you've done with the file parsing, you can release the resources used by the parser : @Cpp TCODParser::~TCODParser() @C void TCOD_parser_delete(TCOD_parser_t parser) @Py parser_delete(parser) @Param parser In the C version, the parser handler, returned by TCOD_parser_new. */ ~TCODParser(); // error during parsing. can be called by the parser listener void error(const char *msg, ...); #ifdef TCOD_VISUAL_STUDIO // silly stuff to avoid VS warning #pragma warning(disable: 4251) #endif TCODList defs; #ifdef TCOD_VISUAL_STUDIO // restore warning again #pragma warning(default: 4251) #endif bool hasProperty(const char *name) const; bool getBoolProperty(const char *name) const; int getIntProperty(const char *name) const; int getCharProperty(const char *name) const; float getFloatProperty(const char *name) const; TCODColor getColorProperty(const char *name) const; TCOD_dice_t getDiceProperty(const char *name) const; const char * getStringProperty(const char *name) const; void * getCustomProperty(const char *name) const; TCOD_list_t getListProperty(const char *name, TCOD_value_type_t type) const; private : bool parseEntity(TCODParserStruct *def, ITCODParserListener *listener); TCOD_parser_t data; }; // a parser structure class TCODLIB_API TCODParserStruct { public : /** @PageName parser_str @FuncTitle Adding a new flag @FuncDesc Use this function to add a flag property to a structure type. A flag is a simplified boolean property. It cannot be mandatory: either it's present and it's true, or it's absent and it's false.
Note that in the C++ version, the function returns its parent object, allowing for chaining. @Cpp TCODParserStruct* TCODParserStruct::addFlag(const char *name) @C void TCOD_struct_add_flag(TCOD_parser_struct_t str,char *name) @Py struct_add_flag(str,name) @Param str In the C version, the structure handler, returned by TCOD_parser_new_struct. @Param name The name of the flag (in the example, this would be "abstract"). @CppEx itemTypeStruct->addFlag("abstract")->addFlag("static"); @CEx TCOD_struct_add_flag(item_type_struct, "abstract"); @PyEx libtcod.struct_add_flag(item_type_struct, "abstract") */ TCODParserStruct* addFlag(const char *propname); /** @PageName parser_str @FuncTitle Adding a new property @FuncDesc Use this function to add a standard property to a structure type. Check standard property types here.
Note that in the C++ version, the function returns its parent object, allowing for chaining. @Cpp TCODParserStruct* TCODParserStruct::addProperty(const char *name, TCOD_value_type_t type, bool mandatory) @C void TCOD_struct_add_property(TCOD_parser_struct_t str, char *name, TCOD_value_type_t type, bool mandatory) @Py struct_add_property(str, name, type, mandatory) @Param str In the C version, the structure handler, returned by TCOD_parser_new_struct. @Param name The name of the property (in the example, this would be "cost" or "damage" or ...). @Param type The type of the property. It can be a standard type (see this). @Param mandatory Is this property mandatory? If true and the property is not defined in the file, the parser will raise an error. @CppEx itemTypeStruct->addProperty("cost",TCOD_TYPE_INT,true) ->addProperty("weight",TCOD_TYPE_FLOAT,true) ->addProperty("deal_damage",TCOD_TYPE_BOOL,true) ->addProperty("damaged_color",TCOD_TYPE_COLOR,true); @CEx TCOD_struct_add_property(item_type_struct, "cost", TCOD_TYPE_INT, true); TCOD_struct_add_property(item_type_struct, "damages", TCOD_TYPE_DICE, true); TCOD_struct_add_property(item_type_struct, "color", TCOD_TYPE_COLOR, true); TCOD_struct_add_property(item_type_struct, "damaged_color", TCOD_TYPE_COLOR, true); @PyEx libtcod.struct_add_property(item_type_struct, "cost", libtcod.TYPE_INT, True) libtcod.struct_add_property(item_type_struct, "damages", libtcod.TYPE_DICE, True) libtcod.struct_add_property(item_type_struct, "color", libtcod.TYPE_COLOR, True) libtcod.struct_add_property(item_type_struct, "damaged_color", libtcod.TYPE_COLOR, True) */ TCODParserStruct* addProperty(const char *propname, TCOD_value_type_t type, bool mandatory); /** @PageName parser_str @FuncTitle Adding a new value-list property @FuncDesc A value-list property is a string property for which we define the list of allowed values. The parser will raise an error if the file contains an unauthorized value for this property. The first value-list property that you add to a structure type will have the TCOD_TYPE_VALUELIST00 type. The next TCOD_TYPE_VALUELIST01. You can define up to 16 value list property for each structure type. The last one has the type TCOD_TYPE_VALUELIST15. You must provide a value list as a NULL terminated array of strings.
Note that in the C++ version, the function returns its parent object, allowing for chaining. @Cpp TCODParserStruct* TCODParserStruct::addValueList(const char *name, const char **value_list, bool mandatory) @C void TCOD_struct_add_value_list(TCOD_parser_struct_t str, char *name, char **value_list, bool mandatory) @Py struct_add_value_list(str, name, value_list, mandatory) @Param str In the C version, the structure handler, returned by TCOD_parser_new_struct. @Param name The name of the property (in the example, this would be "damage_type"). @Param value_list The list of allowed strings. @Param mandatory Is this property mandatory ? If true and the property is not defined in the file, the parser will raise an error. @CppEx static const char *damageTypes[] = { "slash", "pierce", "bludgeon", NULL }; // note the ending NULL itemTypeStruct->addValueList("damage_type", damageTypes, true); @CEx static const char *damage_types[] = { "slash", "pierce", "bludgeon", NULL }; TCOD_struct_add_value_list(item_type_struct, "damage_type", damage_types, true); @PyEx damage_types = [ "slash", "pierce", "bludgeon" ] litbcod.struct_add_value_list(item_type_struct, "damage_type", damage_types, True) */ TCODParserStruct* addValueList(const char *propname, const char **value_list, bool mandatory); /** @PageName parser_str @FuncTitle Adding a new list property @FuncDesc Use this function to add a list property to a structure type.
Note that in the C++ version, the function returns its parent object, allowing for chaining. @Cpp TCODParserStruct* TCODParserStruct::addListProperty(const char *name, TCOD_value_type_t type, bool mandatory) @C void TCOD_struct_add_list_property(TCOD_parser_struct_t str, char *name, TCOD_value_type_t type, bool mandatory) @Py struct_add_list_property(str, name, type, mandatory) @Param str In the C version, the structure handler, returned by TCOD_parser_new_struct. @Param name The name of the property (in the example, this would be "cost" or "damages" or ...). @Param type The type of the list elements. It must be a standard type (see this). It cannot be TCOD_TYPE_LIST. @Param mandatory Is this property mandatory ? If true and the property is not defined in the file, the parser will raise an error. @CppEx itemTypeStruct->addListProperty("intList",TCOD_TYPE_INT,true) ->addListProperty("floatList",TCOD_TYPE_FLOAT,true) ->addListProperty("stringList",TCOD_TYPE_STRING,true); @CEx TCOD_struct_add_list_property(item_type_struct, "intList", TCOD_TYPE_INT, true); TCOD_struct_add_list_property(item_type_struct, "floatList", TCOD_TYPE_FLOAT, true); TCOD_struct_add_list_property(item_type_struct, "stringList", TCOD_TYPE_STRING, true); @PyEx libtcod.struct_add_list_property(item_type_struct, "intList", libtcod.TYPE_INT, True) libtcod.struct_add_list_property(item_type_struct, "floatList", libtcod.TYPE_FLOAT, True) libtcod.struct_add_list_property(item_type_struct, "stringList", libtcod.TYPE_STRING, True) */ TCODParserStruct* addListProperty(const char *propname, TCOD_value_type_t type, bool mandatory); /** @PageName parser_str @FuncTitle Adding a sub-structure @FuncDesc A structure can contain others structures. You can tell the parser which structures are allowed inside one structure type with this function.
Note that in the C++ version, the function returns its parent object, allowing for chaining. @Cpp TCODParserStruct* TCODParserStruct::addStructure(TCODParserStruct *sub_structure) @C void TCOD_struct_add_structure(TCOD_parser_struct_t str, TCOD_parser_struct_t sub_structure) @Py struct_add_structure(str, sub_structure) @Param str In the C version, the structure handler, returned by TCOD_parser_new_struct. @Param sub_structure The structure type that can be embedded. @CppEx // The item_type structure can contain itself itemTypeStruct->addStructure(itemTypeStruct); @CEx TCOD_struct_add_value_list(item_type_struct, item_type_struct); @PyEx libtcod.struct_add_value_list(item_type_struct, item_type_struct) */ TCODParserStruct* addStructure(TCODParserStruct *sub_entity); /** @PageName parser_str @FuncTitle Getting a structure type's name @FuncDesc You can retrieve the name of the structure type with these functions. Warning ! Do not confuse the structure type's name with the structure's name :

item_type "sword" { ... }

Here, the structure type's name is "item_type", the structure name is "sword". Obviously, the structure name cannot be retrieved from the TCODParserStruct object because it's only known at "runtime" (while parsing the file). @Cpp const char *TCODParserStruct::getName() const @C const char *TCOD_struct_get_name(TCOD_parser_struct_t str) @Py struct_get_name(str) @Param str In the C version, the structure handler, returned by TCOD_parser_new_struct. @CppEx const char *structName = itemTypeStruct->getName(); // returns "item_type" @CEx const char *struct_name = TCOD_struct_get_name(item_type_struct); @PyEx struct_name = libtcod.struct_get_name(item_type_struct) */ const char *getName() const; /** @PageName parser_str @FuncTitle Checking if a property is mandatory @FuncDesc You can know if a property is mandatory : @Cpp bool TCODParserStruct::isPropertyMandatory(const char *name) const @C bool TCOD_struct_is_mandatory(TCOD_parser_struct_t str,const char *name) @Py struct_is_mandatory(str,name) @Param str In the C version, the structure handler, returned by TCOD_parser_new_struct. @Param name The name of the property, as defined when you called addProperty or addValueList or addListProperty. @CppEx bool costMandatory = itemTypeStruct->isPropertyMandatory("cost"); @CEx bool cost_mandatory = TCOD_struct_is_mandatory(item_type_struct, "cost"); @PyEx cost_mandatory = libtcod.struct_is_mandatory(item_type_struct, "cost") */ bool isPropertyMandatory(const char *propname) const; /** @PageName parser_str @FuncTitle Retrieving the type of a property @FuncDesc You get the type of a property : In the case of a list property, the value returned is a bitwise or of TCOD_TYPE_LIST and the list element's type. For example, for a list of int, it will return TCOD_TYPE_LIST | TCOD_TYPE_INT. @Cpp TCOD_value_type_t TCODParserStruct::getPropertyType(const char *name) const @C TCOD_value_type_t TCOD_struct_get_type(TCOD_parser_struct_t str, const char *name) @Py struct_get_type(str, name) @Param str In the C version, the structure handler, returned by TCOD_parser_new_struct. @Param name The name of the property, as defined when you called addProperty or addValueList or addListProperty. @CppEx TCOD_value_type_t costType = itemTypeStruct->getPropertyType("cost"); // returns TCOD_TYPE_INT TCOD_value_type_t intListType = itemTypeStruct->getPropertyType("intList"); // returns TCOD_TYPE_LIST|TCOD_TYPE_INT @CEx TCOD_value_type_t cost_type = TCOD_struct_get_type(item_type_struct, "cost"); @PyEx cost_type = libtcod.struct_get_type(item_type_struct, "cost") */ TCOD_value_type_t getPropertyType(const char *propname) const; // private stuff TCOD_parser_struct_t data; }; /** @PageName parser_run @FuncTitle Creating a listener @FuncDesc For basic config files, you don't have to write a listener. Instead, use the default listener. The parser uses a SAX-like approach during the parsing of the file. This means that the whole file is not stored in memory in a tree structure. Instead, it works like a stream parser and raises events. Each event has an associated callback that is provided by a listener : @Cpp class ITCODParserListener { public : virtual bool parserNewStruct(TCODParser *parser,const TCODParserStruct *str,const char *name)=0; virtual bool parserFlag(TCODParser *parser,const char *name)=0; virtual bool parserProperty(TCODParser *parser,const char *name, TCOD_value_type_t type, TCOD_value_t value)=0; virtual bool parserEndStruct(TCODParser *parser,const TCODParserStruct *str, const char *name)=0; virtual void error(const char *msg) = 0; }; @C typedef struct { bool (*new_struct)(TCOD_parser_struct_t str,const char *name); bool (*new_flag)(const char *name); bool (*new_property)(const char *name, TCOD_value_type_t type, TCOD_value_t value); bool (*end_struct)(TCOD_parser_struct_t str, const char *name); void (*error)(const char *msg); } TCOD_parser_listener_t; @Py class ParserListener : def new_struct(str,name) : ... def new_flag(name) : ... def new_property(name,type,value) : ... def end_struct(self, struct, name) : ... def error(msg) : ... */ /** @PageName parser_run @FuncDesc Before running the parser, you have to build a listener : @Cpp class MyListener : public ITCODParserListener { bool parserNewStruct(TCODParser *parser,const TCODParserStruct *str,const char *name) { printf ("new structure type '%s' with name '%s'\n",str->getname(),name ? name : "NULL"); return true; } bool parserFlag(TCODParser *parser,const char *name) { printf ("found new flag '%s'\n",name); return true; } bool parserProperty(TCODParser *parser,const char *name, TCOD_value_type_t type, TCOD_value_t value) { printf ("found new property '%s'\n",name); return true; } bool parserEndStruct(TCODParser *parser,const TCODParserStruct *str,const char *name) { printf ("end of structure type '%s'\n",name); return true; } void error(char *msg) { fprintf(stderr,msg); exit(1); } }; @C bool my_parser_new_struct(TCOD_parser_struct_t str, const char *name) { printf ("new structure type '%s' with name '%s'\n",TCOD_struct_get_name(str),name ? name : "NULL"); return true; } bool my_parser_flag(const char *name) { printf ("found new flag '%s'\n",name); return true; } bool my_parser_property(const char *name, TCOD_value_type_t type, TCOD_value_t value) { printf ("found new property '%s'\n",name); return true; } bool my_parser_end_struct(TCOD_parser_struct_t str, const char *name) { printf ("end of structure type '%s'\n",name); return true; } void my_parser_error(const char *msg) { fprintf(stderr,msg); exit(1); } TCOD_parser_listener_t my_listener = { my_parser_new_struct, my_parser_flag, my_parser_property, my_parser_end_struct, my_parser_error }; @Py class MyListener: def new_struct(self, struct, name): print 'new structure type', libtcod.struct_get_name(struct), ' named ', name return True def new_flag(self, name): print 'new flag named ', name return True def new_property(self,name, typ, value): type_names = ['NONE', 'BOOL', 'CHAR', 'INT', 'FLOAT', 'STRING', 'COLOR', 'DICE'] if typ == libtcod.TYPE_COLOR : print 'new property named ', name,' type ',type_names[typ], ' value ', value.r, value.g, value.b elif typ == libtcod.TYPE_DICE : print 'new property named ', name,' type ',type_names[typ], ' value ', value.nb_rolls, value.nb_faces, value.multiplier, value.addsub else: print 'new property named ', name,' type ',type_names[typ], ' value ', value return True def end_struct(self, struct, name): print 'end structure type', libtcod.struct_get_name(struct), ' named ', name return True def error(self,msg): print 'error : ', msg return True */ // sax event listener class TCODLIB_API ITCODParserListener { public : virtual ~ITCODParserListener(){} /** @PageName parser_run @FuncTitle Handling 'newStruct' events @FuncDesc This callback is called each time the parser find a new structure declaration in the file. Example :
item_type "blade" { // <= newStruct event here
	...
}
It must return true if everything is right, false if there is an error and the parser must exit. @Cpp bool ITCODParserListener::parserNewStruct(TCODParser *parser,TCODParserStruct *str,const char *name) @C bool new_struct(TCOD_parser_struct_t str,const char *name) @Py new_struct(str,name) @Param parser In the C++ version, the parser object, returned by TCODParser constructor. It's used for error handling. @Param str The structure type. Can be used to retrieve the type's name with getName. In the example above, this would be "item_type". @Param name The name of the structure or NULL if no name is present in the file. In the example above, this would be "blade". */ virtual bool parserNewStruct(TCODParser *parser,const TCODParserStruct *str,const char *name)=0; /** @PageName parser_run @FuncTitle Handling 'newFlag' events @FuncDesc This callback is called each time the parser find a new flag in the file. Example :
item_type "blade" {
	abstract  // <= newFlag event here
}
It must return true if everything is right, false if there is an error and the parser must exit. @Cpp bool ITCODParserListener::parserFlag(TCODParser *parser,const char *name) @C bool new_flag(const char *name) @Py new_flag(name) @Param parser In the C++ version, the parser object, returned by TCODParser constructor. It's used for error handling. @Param name The name of the flag. In the example, this would be "abstract". */ virtual bool parserFlag(TCODParser *parser,const char *name)=0; /** @PageName parser_run @FuncTitle Handling 'newProperty' events @FuncDesc This callback is called each time the parser find a new property in the file. Example :
item_type "blade" {
	abstract
	cost=300 // <= newProperty event here
}
It must return true if everything is right, false if there is an error and the parser must exit. @Cpp bool ITCODParserListener::parserProperty(TCODParser *parser,const char *name, TCOD_value_type_t type, TCOD_value_t value) @C bool new_property(const char *name, TCOD_value_type_t type, TCOD_value_t value) @Py new_property(name,type,value) @Param parser In the C++ version, the parser object, returned by TCODParser constructor. It's used for error handling. @Param name The name of the property. In the example, this would be "cost". @Param type The type of the property as defined when you called addProperty or addValueList. In the example, this would be TCOD_TYPE_INT. @Param value The value of the property, stored in a generic value structure. In the example, we would have value.i == 300. In the case of a value-list property, the type would reflect the list id (between TCOD_TYPE_VALUELIST00 and TCOD_TYPE_VALUELIST15) and value.s would contain the actual string. */ virtual bool parserProperty(TCODParser *parser,const char *propname, TCOD_value_type_t type, TCOD_value_t value)=0; /** @PageName parser_run @FuncTitle Handling 'endStruct' events @FuncDesc This callback is called each time the parser find the end of a structure declaration in the file. Example :
item_type "blade" {
	...
} // <= endStruct event here
It must return true if everything is right, false if there is an error and the parser must exit. @Cpp bool ITCODParserListener::parserEndStruct(TCODParser *parser,TCODParserStruct *str,const char *name) @C bool end_struct(TCOD_parser_struct_t str,const char *name) @Py end_struct(str,name) @Param parser In the C++ version, the parser object, returned by TCODParser constructor. It's used for error handling. @Param str The structure type. Can be used to retrieve the type's name with getName. In the example above, this would be "item_type". @Param name The name of the structure or NULL if no name is present in the file. In the example above, this would be "blade". */ virtual bool parserEndStruct(TCODParser *parser,const TCODParserStruct *str, const char *name)=0; /** @PageName parser_run @FuncTitle Handling errors @FuncDesc There are two kind of errors : * Errors that are detected by the parser itself (malformed file, bad value syntax for a property, missing mandatory property in a structure, ...). * Errors that you detect in your callbacks. When the parser finds an error in the file, it will call the error callback and stop : @Cpp void ITCODParserListener::error(const char *msg) @C void error(const char *msg) @Py error(msg) @Param msg The error message from the parser with the file name and the line number. */ /** @PageName parser_run @FuncDesc If you find an error in your callback, you have to call the parser error function. It will add the file name and line number to your error message, and then call your error callback : The code in the example below will result in your error callback called with the following string : "error in <filename> line <line_number> : Bad cost value %d. Cost must be between 0 and 1000" @Cpp void TCODParser::error(const char *msg, ...) @C void TCOD_parser_error(const char *msg, ...) @Py parser_error(msg) @Param msg printf-like format string for your error message. @CppEx parser->error("Bad cost value %d. Cost must be between 0 and 1000", value.i); @CEx TCOD_parser_error("Bad cost value %d. Cost must be between 0 and 1000", value.i); @PyEx libtcod.parser_error("Bad cost value %d. Cost must be between 0 and 1000"%( value )) */ virtual void error(const char *msg) = 0; }; /** @PageName parser_types @PageFather parser @PageTitle Standard types @FuncDesc The parser can parse natively several data types. It stores them in a generic union : @C typedef struct { int nb_rolls; int nb_faces; float multiplier; float addsub; } TCOD_dice_t; typedef union { bool b; char c; int32_t i; float f; char *s; TCOD_color_t col; TCOD_dice_t dice; TCOD_list_t list; void *custom; } TCOD_value_t; */ /** @PageName parser_types @FuncDesc Possible types are defined by the TCOD_value_type_t enumeration : For Python, remove TCOD_ : libtcod.TYPE_BOOL
TCOD_value_type_tValue in fileTCOD_value_t
TCOD_TYPE_BOOLtrue
false
value.b == true/false
TCOD_TYPE_CHARdecimal notation : 0 .. 255
hexadecimal notation : 0x00 .. 0xff
char notation : 'a' ';' ...
Special characters :
'\n' : carriage return (ascii 13)
'\t' : tabulation (ascii 9)
'\r' : line feed (ascii 10)
'\\' : antislash (ascii 92)
'\"' : double-quote (ascii 34)
'\'' : simple quote (ascii 39)
'\xHH' : hexadecimal value, same as 0xHH, HH between 0 and FF
'\NNN' : octal value, NNN between 0 and 377
value.c == The corresponding ascii code
TCOD_TYPE_INTdecimal notation : -2147483648 .. 2147483647
hexadecimal notation : 0x0 .. 0xFFFFFFFF
value.i == the integer value
TCOD_TYPE_FLOATAny format parsable by atof. Examples:
3.14159
1.25E-3
value.f == the float value
TCOD_TYPE_STRINGA double-quote delimited string :
"This is a string"
Support the same special characters as TCOD_TYPE_CHAR.
value.s == the corresponding string.
Warning ! If you want to store this string, you have to duplicate it (with strdup) as it will be overwritten by the parser
TCOD_TYPE_COLORdecimal notation : "16,32,64"
hexadecimal notation : "#102040"
value.col == the color.
TCOD_TYPE_DICE[multiplier (x|*)] nb_rolls (d|D) nb_faces [(+|-) addsub] :
"3d6"
"3D6+2"
"0.5x3d6-2"
"2*3d8"
value.dice == the dice components
TCOD_TYPE_VALUELISTxxSame as TCOD_TYPE_STRINGvalue.s == the string value from the value list
TCOD_TYPE_LIST[ <value1>,<value2>,... ]value.list == the TCOD_list_t containing the elements
To define a list type, use the appropriate function (TCODParserStruct::addListProperty / TCOD_parser_add_list_property) and specify the type of the elements in the list. Lists of list are not supported. */ #endif libtcod-1.6.4+dfsg/include/path.h000066400000000000000000000071341321276576200166310ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_PATH_H #define _TCOD_PATH_H #include "libtcod_portability.h" #include "fov_types.h" #ifdef __cplusplus extern "C" { #endif typedef float (*TCOD_path_func_t)( int xFrom, int yFrom, int xTo, int yTo, void *user_data ); typedef void *TCOD_path_t; TCODLIB_API TCOD_path_t TCOD_path_new_using_map(TCOD_map_t map, float diagonalCost); TCODLIB_API TCOD_path_t TCOD_path_new_using_function(int map_width, int map_height, TCOD_path_func_t func, void *user_data, float diagonalCost); TCODLIB_API bool TCOD_path_compute(TCOD_path_t path, int ox,int oy, int dx, int dy); TCODLIB_API bool TCOD_path_walk(TCOD_path_t path, int *x, int *y, bool recalculate_when_needed); TCODLIB_API bool TCOD_path_is_empty(TCOD_path_t path); TCODLIB_API int TCOD_path_size(TCOD_path_t path); TCODLIB_API void TCOD_path_reverse(TCOD_path_t path); TCODLIB_API void TCOD_path_get(TCOD_path_t path, int index, int *x, int *y); TCODLIB_API void TCOD_path_get_origin(TCOD_path_t path, int *x, int *y); TCODLIB_API void TCOD_path_get_destination(TCOD_path_t path, int *x, int *y); TCODLIB_API void TCOD_path_delete(TCOD_path_t path); /* Dijkstra stuff - by Mingos*/ typedef void *TCOD_dijkstra_t; TCODLIB_API TCOD_dijkstra_t TCOD_dijkstra_new (TCOD_map_t map, float diagonalCost); TCODLIB_API TCOD_dijkstra_t TCOD_dijkstra_new_using_function(int map_width, int map_height, TCOD_path_func_t func, void *user_data, float diagonalCost); TCODLIB_API void TCOD_dijkstra_compute (TCOD_dijkstra_t dijkstra, int root_x, int root_y); TCODLIB_API float TCOD_dijkstra_get_distance (TCOD_dijkstra_t dijkstra, int x, int y); TCODLIB_API bool TCOD_dijkstra_path_set (TCOD_dijkstra_t dijkstra, int x, int y); TCODLIB_API bool TCOD_dijkstra_is_empty(TCOD_dijkstra_t path); TCODLIB_API int TCOD_dijkstra_size(TCOD_dijkstra_t path); TCODLIB_API void TCOD_dijkstra_reverse(TCOD_dijkstra_t path); TCODLIB_API void TCOD_dijkstra_get(TCOD_dijkstra_t path, int index, int *x, int *y); TCODLIB_API bool TCOD_dijkstra_path_walk (TCOD_dijkstra_t dijkstra, int *x, int *y); TCODLIB_API void TCOD_dijkstra_delete (TCOD_dijkstra_t dijkstra); #ifdef __cplusplus } #endif #endif libtcod-1.6.4+dfsg/include/path.hpp000066400000000000000000000534001321276576200171660ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_PATH_HPP #define _TCOD_PATH_HPP #include "fov.hpp" #include "path.h" class TCODLIB_API ITCODPathCallback { public : virtual ~ITCODPathCallback() {} virtual float getWalkCost( int xFrom, int yFrom, int xTo, int yTo, void *userData ) const = 0; }; /** @PageName path @PageTitle Path finding @PageCategory Roguelike toolkits @PageDesc This toolkit allows one to easily calculate the optimal path between two points in your dungeon by using either the A* algorithm or Dijkstra's algorithm. Please note that the paths generated with the two algorithms may differ slightly. Due to how they're implemented, A* will usually prefer diagonal moves over orthogonal, while Dijkstra will have the opposite preference. In other words, paths from point X to point Y will look like this:
Dijkstra:      A*:
..........   ..........
.X........   .X*.......
..*.......   ...**.....
...*......   .....**...
....****Y.   .......*Y.
..........   ..........
*/ class TCODLIB_API TCODPath { public : /** @PageName path_init @PageFather path @PageTitle Creating a path @FuncTitle Allocating a pathfinder from a map @FuncDesc First, you have to allocate a path using a map from the Field of view module. @Cpp TCODPath::TCODPath(const TCODMap *map, float diagonalCost=1.41f) TCODDijkstra::TCODDijkstra(const TCODMap *map, float diagonalCost=1.41f) @C TCOD_path_t TCOD_path_new_using_map(TCOD_map_t map, float diagonalCost) TCOD_dijkstra_t TCOD_dijkstra_new(TCOD_map_t map, float diagonalCost) @Py path_new_using_map(map, diagonalCost=1.41) dijkstra_new(map, diagonalCost=1.41) @C# TCODPath(TCODMap map, float diagonalCost) TCODPath(TCODMap map) TCODDijkstra(TCODMap map, float diagonalCost) TCODDijkstra(TCODMap map) @Param map The map. The path finder will use the 'walkable' property of the cells to find a path. @Param diagonalCost Cost of a diagonal movement compared to an horizontal or vertical movement. On a standard cartesian map, it should be sqrt(2) (1.41f). It you want the same cost for all movements, use 1.0f. If you don't want the path finder to use diagonal movements, use 0.0f. @CppEx // A* : TCODMap *myMap = new TCODMap(50,50); TCODPath *path = new TCODPath(myMap); // allocate the path // Dijkstra: TCODMap *myMap = new TCODMap(50,50); TCODDijkstra *dijkstra = new TCODDijkstra(myMap); // allocate the path @CEx // A* : TCOD_map_t my_map=TCOD_map_new(50,50,true); TCOD_path_t path = TCOD_path_new_using_map(my_map,1.41f); // Dijkstra : TCOD_map_t my_map=TCOD_map_new(50,50,true); TCOD_dijkstra_t dijk = TCOD_dijkstra_new(my_map,1.41f); @PyEx # A* : my_map=libtcod.map_new(50,50,True) path = libtcod.path_new_using_map(my_map) # Dijkstra my_map=libtcod.map_new(50,50,True) dijk = libtcod.dijkstra_new(my_map) */ TCODPath(const TCODMap *map, float diagonalCost=1.41f); /** @PageName path_init @FuncTitle Allocating a pathfinder using a callback @FuncDesc Since the walkable status of a cell may depend on a lot of parameters (the creature type, the weather, the terrain type...), you can also create a path by providing a function rather than relying on a TCODMap. @Cpp // Callback : class ITCODPathCallback { public: virtual float getWalkCost( int xFrom, int yFrom, int xTo, int yTo, void *userData ) const = 0; }; // A* constructor: TCODPath::TCODPath(int width, int height, const ITCODPathCallback *callback, void *userData, float diagonalCost=1.41f) // Dijkstra constructor TCODDijkstra::TCODDijkstra(int width, int height, const ITCODPathCallback *callback, void *userData, float diagonalCost=1.41f) @C typedef float (*TCOD_path_func_t)( int xFrom, int yFrom, int xTo, int yTo, void *user_data ) TCOD_path_t TCOD_path_new_using_function(int width, int height, TCOD_path_func_t callback, void *user_data, float diagonalCost) TCOD_dijkstra_t TCOD_dijkstra_new_using_function(int width, int height, TCOD_path_func_t callback, void *user_data, float diagonalCost) @Py def path_func(xFrom,yFrom,xTo,yTo,userData) : ... path_new_using_function(width, height, path_func, user_data=0, diagonalCost=1.41) dijkstra_new_using_function(width, height, path_func, user_data=0, diagonalCost=1.41) @C# TCODPath(int width, int height, ITCODPathCallback listener, float diagonalCost) TCODPath(int width, int height, ITCODPathCallback listener) TCODDijkstra(int width, int height, ITCODPathCallback listener, float diagonalCost) TCODDijkstra(int width, int height, ITCODPathCallback listener) @Param width,height The size of the map (in map cells). @Param callback A custom function that must return the walk cost from coordinates xFrom,yFrom to coordinates xTo,yTo. The cost must be > 0.0f if the cell xTo,yTo is walkable. It must be equal to 0.0f if it's not. You must not take additional cost due to diagonal movements into account as it's already done by the pathfinder. @Param userData Custom data that will be passed to the function. @Param diagonalCost Cost of a diagonal movement compared to an horizontal or vertical movement. On a standard cartesian map, it should be sqrt(2) (1.41f). It you want the same cost for all movements, use 1.0f. If you don't want the path finder to use diagonal movements, use 0.0f. @CppEx class MyCallback : public ITCODPathCallback { public : float getWalkCost(int xFrom, int yFrom, int xTo, int yTo, void *userData ) const { ... } }; TCODPath *path = new TCODPath(50,50,new MyCallback(),NULL); // allocate the path TCODDijkstra *dijkstra = new TCODDijkstra(50,50,new MyCallback(),NULL); // allocate Dijkstra @CEx float my_func(int xFrom, int yFrom, int xTo, int yTo, void *user_data) { ... } TCOD_path_t path = TCOD_path_new_using_function(50,50,my_func,NULL,1.41f); TCOD_dijkstra_t dijkstra = TCOD_dijkstra_new_using_function(50,50,my_func,NULL,1.41f); @PyEx def my_func(xFrom, yFrom, xTo, yTo, user_data) : # return a float cost for this movement return 1.0 path = libtcod.path_new_using_function(50,50,my_func) dijkstra = libtcod.dijkstra_new_using_function(50,50,my_func) */ TCODPath(int width, int height, const ITCODPathCallback *listener, void *userData, float diagonalCost=1.41f); /** @PageName path_init @FuncTitle Destroying a path @FuncDesc To release the resources used by a path, destroy it with : @Cpp TCODPath::~TCODPath() TCODDijkstra::~TCODDijkstra() @C void TCOD_path_delete(TCOD_path_t path) void TCOD_dijkstra_delete(TCOD_dijkstra_t dijkstra) @Py path_delete(path) dijkstra_delete(dijkstra) @C# void TCODPath::Dispose() void TCODDijkstra::Dispose() @Param path In the C version, the path handler returned by one of the TCOD_path_new_* function. @Param dijkstra In the C version, the path handler returned by one of the TCOD_dijkstra_new* function. @CppEx TCODPath *path = new TCODPath(myMap); // allocate the path // use the path... delete path; // destroy the path TCODDijkstra *dijkstra = new TCODDijkstra(myMap); // allocate the path // use the path... delete dijkstra; // destroy the path @CEx TCOD_path_t path = TCOD_path_new_using_map(my_map); // use the path ... TCOD_path_delete(path); TCOD_dijkstra_t dijkstra = TCOD_dijkstra_new(my_map); // use the path ... TCOD_dijkstra_delete(dijkstra); @PyEx path = libtcod.path_new_using_map(my_map) # use the path ... libtcod.path_delete(path) dijkstra = libtcod.dijkstra_new(my_map) # use the path ... libtcod.dijkstra_delete(dijkstra) */ virtual ~TCODPath(); /** @PageName path_compute @PageFather path @PageTitle Computing the path @FuncTitle Computing an A* path @FuncDesc Once you created a TCODPath object, you can compute the path between two points: @Cpp bool TCODPath::compute(int ox, int oy, int dx, int dy) @C bool TCOD_path_compute(TCOD_path_t path, int ox,int oy, int dx, int dy) @Py path_compute(path, ox, oy, dx, dy) @C# void TCODPath::compute(int ox, int oy, int dx, int dy) @Param path In the C version, the path handler returned by a creation function. @Param ox,oy Coordinates of the origin of the path. @Param dx,dy Coordinates of the destination of the path. Both points should be inside the map, and at a walkable position. The function returns false if there is no possible path. @CppEx TCODMap *myMap = new TCODMap(50,50); TCODPath *path = new TCODPath(myMap); // allocate the path path->compute(5,5,25,25); // calculate path from 5,5 to 25,25 @CEx TCOD_map_t my_map=TCOD_map_new(50,50); TCOD_path_t path = TCOD_path_new_using_map(my_map); TCOD_path_compute(path,5,5,25,25); @PyEx my_map=libtcod.map_new(50,50) path = libtcod.path_new_using_map(my_map) libtcod.path_compute(path,5,5,25,25) */ bool compute(int ox, int oy, int dx, int dy); /** @PageName path_compute @FuncTitle Reversing a path @FuncDesc Once you computed a path, you can exchange origin and destination : @Cpp void TCODPath::reverse() void TCODDijkstra::reverse() @C void TCOD_path_reverse(TCOD_path_t path) void TCOD_dijkstra_reverse(TCOD_dijkstra_t dijkstra) @Py path_reverse(path) dijkstra_reverse(dijkstra) @C# void TCODPath::reverse() void TCODDijkstra::reverse() @Param path In the C version, the path handler returned by a creation function. @CppEx TCODMap *myMap = new TCODMap(50,50); TCODPath *path = new TCODPath(myMap); // allocate the path path->compute(5,5,25,25); // calculate path from 5,5 to 25,25 path->reverse(); // now the path goes from 25,25 to 5,5 @CEx TCOD_map_t my_map=TCOD_map_new(50,50); TCOD_path_t path = TCOD_path_new_using_map(my_map); TCOD_path_compute(path,5,5,25,25); // calculate path from 5,5 to 25,25 TCOD_path_reverse(path); // now the path goes from 25,25 to 5,5 @PyEx my_map=libtcod.map_new(50,50) path = libtcod.path_new_using_map(my_map) libtcod.path_compute(path,5,5,25,25) # calculate path from 5,5 to 25,25 libtcod.path_reverse(path) # now the path goes from 25,25 to 5,5 */ void reverse(); /** @PageName path_read @PageTitle Reading path information @PageFather path @PageDescDesc Once the path has been computed, you can get information about it using of one those functions. @FuncTitle Getting the path origin and destination @FuncDesc You can read the current origin and destination cells with getOrigin/getDestination. Note that when you walk the path, the origin changes at each step. @Cpp void TCODPath::getOrigin(int *x,int *y) const void TCODPath::getDestination(int *x,int *y) const @C void TCOD_path_get_origin(TCOD_path_t path, int *x, int *y) void TCOD_path_get_destination(TCOD_path_t path, int *x, int *y) @Py path_get_origin(path) # returns x,y path_get_destination(path) # returns x,y @C# void TCODPath::getOrigin(out int x, out int y) void TCODPath::getDestination(out int x, out int y) @Param path In the C version, the path handler returned by a creation function. @Param x,y The function returns the cell coordinates in these variables */ void getOrigin(int *x,int *y) const; void getDestination(int *x,int *y) const; /** @PageName path_read @FuncTitle Getting the path length @FuncDesc You can get the number of steps needed to reach destination : @Cpp int TCODPath::size() const int TCODDijkstra::size() const @C int TCOD_path_size(TCOD_path_t path) int TCOD_dijkstra_size(TCOD_dijkstra_t dijkstra) @Py path_size(path) dijkstra_size(dijkstra) @C# int TCODPath::size() int TCODDijkstra::size() @Param path, dijkstra In the C version, the path handler returned by a creation function. */ int size() const; /** @PageName path_read @FuncTitle Read the path cells' coordinates @FuncDesc You can get the coordinates of each point along the path : @Cpp void TCODPath::get(int index, int *x, int *y) const void TCODDijkstra::get(int index, int *x, int *y) const @C void TCOD_path_get(TCOD_path_t path, int index, int *x, int *y) void TCOD_dijkstra_get(TCOD_dijkstra_t dijkstra, int index, int *x, int *y) @Py path_get(path, index) # returns x,y dijkstra_get(dijkstra, index) # returns x,y @C# int TCODPath::size() int TCODDijkstra::size() @Param path, dijkstra In the C version, the path handler returned by a creation function. @Param index Step number. 0 <= index < path size @Param x,y Address of the variables receiving the coordinates of the point. @CppEx for (int i=0; i < path->size(); i++ ) { int x,y; path->get(i,&x,&y); printf ("Astar coord : %d %d\n", x,y ); } for (int i=0; i < dijkstra->size(); i++ ) { int x,y; dijkstra->get(i,&x,&y); printf ("Dijkstra coord : %d %d\n", x,y ); } @CEx int i; for (i=0; i < TCOD_path_size(path); i++ ) { int x,y; TCOD_path_get(path,i,&x,&y); printf ("Astar coord : %d %d\n", x,y ); } for (i=0; i < TCOD_dijkstra_size(dijkstra); i++ ) { int x,y; TCOD_dijkstra_get(dijkstra,i,&x,&y); printf ("Dijsktra coord : %d %d\n", x,y ); } @PyEx for i in range (libtcod.path_size(path)) : x,y=libtcod.path_get(path,i) print 'Astar coord : ',x,y for i in range (libtcod.dijkstra_size(dijkstra)) : x,y=libtcod.dijkstra_get(dijkstra,i) print 'Dijkstra coord : ',x,y */ void get(int index, int *x, int *y) const; /** @PageName path_read @FuncTitle Checking if the path is empty @FuncDesc If you want a creature to follow the path, a more convenient way is to walk the path : You know when you reached destination when the path is empty : @Cpp bool TCODPath::isEmpty() const bool TCODDijkstra::isEmpty() const @C bool TCOD_path_is_empty(TCOD_path_t path) bool TCOD_dijkstra_is_empty(TCOD_dijkstra_t dijkstra) @Py path_is_empty(path) dijkstra_is_empty(dijkstra) @C# bool TCODPath::isEmpty() bool TCODDijkstra::isEmpty() @Param path, dijkstra In the C version, the path handler returned by a creation function. */ bool isEmpty() const; /** @PageName path_read @FuncTitle Walking the path @FuncDesc You can walk the path and go to the next step with : Note that walking the path consume one step (and decrease the path size by one). The function returns false if recalculateWhenNeeded is false and the next cell on the path is no longer walkable, or if recalculateWhenNeeded is true, the next cell on the path is no longer walkable and no other path has been found. Also note that recalculateWhenNeeded only applies to A*. @Cpp bool TCODPath::walk(int *x, int *y, bool recalculateWhenNeeded) bool TCODDijkstra::walk(int *x, int *y) @C bool TCOD_path_walk(TCOD_path_t path, int *x, int *y, bool recalculate_when_needed) bool TCOD_dijkstra_walk(TCOD_dijkstra_t dijkstra, int *x, int *y) @Py path_walk(TCOD_path_t path, recalculate_when_needed) # returns x,y or None,None if no path dijkstra_walk(TCOD_dijkstra_t dijkstra) @C# bool TCODPath::walk(ref int x, ref int y, bool recalculateWhenNeeded) bool TCODDijkstra::walk(ref int x, ref int y) @Param path, dijkstra In the C version, the path handler returned by a creation function. @Param x,y Address of the variables receiving the coordinates of the next point. @Param recalculateWhenNeeded If the next point is no longer walkable (another creature may be in the way), recalculate a new path and walk it. @CppEx while (! path->isEmpty()) { int x,y; if (path->walk(&x,&y,true)) { printf ("Astar coord: %d %d\n",x,y ); } else { printf ("I'm stuck!\n" ); break; } } while (! dijkstra->isEmpty()) { int x,y; if (dijkstra->walk(&x,&y)) { printf ("Dijkstra coord: %d %d\n",x,y ); } else { printf ("I'm stuck!\n" ); break; } } @CEx while (! TCOD_path_is_empty(path)) { int x,y; if (TCOD_path_walk(path,&x,&y,true)) { printf ("Astar coord: %d %d\n",x,y ); } else { printf ("I'm stuck!\n" ); break; } } while (! TCOD_dijkstra_is_empty(dijkstra)) { int x,y; if (TCOD_dijkstra_walk(dijkstra,&x,&y)) { printf ("Dijkstra coord: %d %d\n",x,y ); } else { printf ("I'm stuck!\n" ); break; } } @PyEx while not libtcod.path_is_empty(path)) : x,y=libtcod.path_walk(path,True) if not x is None : print 'Astar coord: ',x,y else : print "I'm stuck!" break while not libtcod.dijkstra_is_empty(dijkstra)) : x,y=libtcod.dijkstra_walk(dijkstra,True) if not x is None : print 'Dijkstra coord: ',x,y else : print "I'm stuck!" break */ bool walk(int *x, int *y, bool recalculateWhenNeeded); protected : friend float TCOD_path_func(int xFrom, int yFrom, int xTo,int yTo, void *data); TCOD_path_t data; struct WrapperData { void *userData; const ITCODPathCallback *listener; } cppData; }; //Dijkstra kit class TCODLIB_API TCODDijkstra { public: TCODDijkstra (TCODMap *map, float diagonalCost=1.41f); TCODDijkstra (int width, int height, const ITCODPathCallback *listener, void *userData, float diagonalCost=1.41f); ~TCODDijkstra (void); /** @PageName path_compute @FuncTitle Computing a Dijkstra grid @FuncDesc In case of Dijkstra, this works in a slightly different way. In order to be able to compute a path, Dijkstra must first analyse the distances from the selected root (origin) node to all other nodes: @Cpp void TCODDijkstra::compute(int rootX, int rootY) @C void TCOD_dijkstra_compute(TCOD_dijkstra_t dijkstra, int root_x, int root_y) @Py dijkstra_compute(dijkstra, root_x, root_y) @C# void TCODDijkstra::compute(int rootX, int rootY) @Param dijkstra In the C version, the path handler returned by a creation function. @Param root_x,root_y Coordinates of the root node (origin) of the path. The coordinates should be inside the map, at a walkable position. Otherwise, the function's behaviour will be undefined. */ void compute (int rootX, int rootY); /** @PageName path_compute @FuncTitle Computing a path from a Dijkstra grid @FuncDesc After the map is analysed and all the distances from the root node are known, an unlimited number of paths can be set, all originating at the root node, using: The path setting function will return true if there's a path from the root node to the destination node. Otherwise, it will return false. @Cpp bool TCODDijkstra::setPath(int toX, int toY) @C bool TCOD_dijkstra_path_set(TCOD_dijkstra_t dijkstra, int to_x, int to_y) @Py dijkstra_path_set(dijkstra, to_x, to_y) @C# bool TCODDijkstra::setPath(int toX, int toY) @Param dijkstra In the C version, the path handler returned by a creation function. @Param to_x,to_y Coordinates of the destination node of the path. @CppEx TCODMap *myMap = new TCODMap(50,50); TCODDijkstra *dijkstra = new TCODDijkstra(myMap); // allocate the path dijkstra->compute(25,25); // calculate distance from 25,25 to all other nodes dijkstra->setPath(5,5); // calculate a path to node 5,5 dijkstra->setPath(45,45); //calculate another path from the same origin @CEx TCOD_map_t my_map=TCOD_map_new(50,50); TCOD_dijkstra_t dijkstra = TCOD_dijkstra_new(my_map); TCOD_dijkstra_compute(dijkstra,25,25); TCOD_dijkstra_path_set(dijkstra,5,5); TCOD_dijkstra_path_set(dijkstra,45,45); @PyEx my_map=libtcod.map_new(50,50) dijkstra = libtcod.dijkstra_new(my_map) libtcod.dijkstra_compute(dijkstra,25,25) libtcod.dijkstra_path_set(dijkstra,5,5) libtcod.dijkstra_path_set(dijkstra,45,45) */ bool setPath (int toX, int toY); /** @PageName path_read @FuncTitle Getting the distance from a cell to the root node @FuncDesc You can get the distance of any set of coordinates from the root node: Note that if the coordinates x,y are outside of the map or are a non-walkable position, the function will return -1.0f. This functionality is only available for Dijkstra's algorithm. @Cpp float TCODDijkstra::getDistance(int x, int y) @C float TCOD_dijkstra_get_distance(TCOD_dijkstra_t dijkstra, int x, int y) @Py dijkstra_get_distance(dijkstra, x, y) @C# float TCODDijkstra::getDistance(int x, int y) @Param dijkstra In the C version, the path handler returned by a creation function. @Param x,y The coordinates whose distance from the root node are to be checked */ float getDistance (int x, int y); bool walk (int *x, int *y); bool isEmpty() const; void reverse(); int size() const; void get(int index, int *x, int *y) const; private: TCOD_dijkstra_t data; struct WrapperData { void *userData; const ITCODPathCallback *listener; } cppData; }; #endif libtcod-1.6.4+dfsg/include/sys.h000066400000000000000000000140511321276576200165070ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_SYS_H #define _TCOD_SYS_H #include "libtcod_portability.h" #include "list.h" #include "image.h" #include "mouse_types.h" #ifdef __cplusplus extern "C" { #endif TCODLIB_API void TCOD_sys_startup(void); TCODLIB_API void TCOD_sys_shutdown(void); #ifdef TCOD_OSUTIL_SUPPORT TCODLIB_API uint32_t TCOD_sys_elapsed_milli(void); TCODLIB_API float TCOD_sys_elapsed_seconds(void); TCODLIB_API void TCOD_sys_sleep_milli(uint32_t val); TCODLIB_API void TCOD_sys_set_fps(int val); TCODLIB_API int TCOD_sys_get_fps(void); TCODLIB_API float TCOD_sys_get_last_frame_length(void); #endif #ifdef TCOD_SDL2 TCODLIB_API void TCOD_sys_save_screenshot(const char *filename); TCODLIB_API void TCOD_sys_force_fullscreen_resolution(int width, int height); TCODLIB_API void TCOD_sys_set_renderer(TCOD_renderer_t renderer); TCODLIB_API TCOD_renderer_t TCOD_sys_get_renderer(void); TCODLIB_API void TCOD_sys_get_current_resolution(int *w, int *h); TCODLIB_API void TCOD_sys_get_fullscreen_offsets(int *offx, int *offy); TCODLIB_API void TCOD_sys_get_char_size(int *w, int *h); #endif #ifdef TCOD_IMAGE_SUPPORT TCODLIB_API void TCOD_sys_update_char(int asciiCode, int fontx, int fonty, TCOD_image_t img, int x, int y); #endif #ifdef TCOD_SDL2 TCODLIB_API void *TCOD_sys_get_SDL_window(void); TCODLIB_API void *TCOD_sys_get_SDL_renderer(void); #endif #ifdef TCOD_SDL2 typedef enum { TCOD_EVENT_NONE=0, TCOD_EVENT_KEY_PRESS=1, TCOD_EVENT_KEY_RELEASE=2, TCOD_EVENT_KEY=TCOD_EVENT_KEY_PRESS|TCOD_EVENT_KEY_RELEASE, TCOD_EVENT_MOUSE_MOVE=4, TCOD_EVENT_MOUSE_PRESS=8, TCOD_EVENT_MOUSE_RELEASE=16, TCOD_EVENT_MOUSE=TCOD_EVENT_MOUSE_MOVE|TCOD_EVENT_MOUSE_PRESS|TCOD_EVENT_MOUSE_RELEASE, /* #ifdef TCOD_TOUCH_INPUT */ TCOD_EVENT_FINGER_MOVE=32, TCOD_EVENT_FINGER_PRESS=64, TCOD_EVENT_FINGER_RELEASE=128, TCOD_EVENT_FINGER=TCOD_EVENT_FINGER_MOVE|TCOD_EVENT_FINGER_PRESS|TCOD_EVENT_FINGER_RELEASE, /* #endif */ TCOD_EVENT_ANY=TCOD_EVENT_KEY|TCOD_EVENT_MOUSE|TCOD_EVENT_FINGER, } TCOD_event_t; TCODLIB_API TCOD_event_t TCOD_sys_wait_for_event(int eventMask, TCOD_key_t *key, TCOD_mouse_t *mouse, bool flush); TCODLIB_API TCOD_event_t TCOD_sys_check_for_event(int eventMask, TCOD_key_t *key, TCOD_mouse_t *mouse); #endif /* filesystem stuff */ TCODLIB_API bool TCOD_sys_create_directory(const char *path); TCODLIB_API bool TCOD_sys_delete_file(const char *path); TCODLIB_API bool TCOD_sys_delete_directory(const char *path); TCODLIB_API bool TCOD_sys_is_directory(const char *path); TCODLIB_API TCOD_list_t TCOD_sys_get_directory_content(const char *path, const char *pattern); TCODLIB_API bool TCOD_sys_file_exists(const char * filename, ...); TCODLIB_API bool TCOD_sys_read_file(const char *filename, unsigned char **buf, size_t *size); TCODLIB_API bool TCOD_sys_write_file(const char *filename, unsigned char *buf, uint32_t size); #ifdef TCOD_SDL2 /* clipboard */ TCODLIB_API bool TCOD_sys_clipboard_set(const char *value); TCODLIB_API char *TCOD_sys_clipboard_get(void); #endif /* thread stuff */ typedef void *TCOD_thread_t; typedef void *TCOD_semaphore_t; typedef void *TCOD_mutex_t; typedef void *TCOD_cond_t; /* threads */ TCODLIB_API TCOD_thread_t TCOD_thread_new(int (*func)(void *), void *data); TCODLIB_API void TCOD_thread_delete(TCOD_thread_t th); TCODLIB_API int TCOD_sys_get_num_cores(void); TCODLIB_API void TCOD_thread_wait(TCOD_thread_t th); /* mutex */ TCODLIB_API TCOD_mutex_t TCOD_mutex_new(void); TCODLIB_API void TCOD_mutex_in(TCOD_mutex_t mut); TCODLIB_API void TCOD_mutex_out(TCOD_mutex_t mut); TCODLIB_API void TCOD_mutex_delete(TCOD_mutex_t mut); /* semaphore */ TCODLIB_API TCOD_semaphore_t TCOD_semaphore_new(int initVal); TCODLIB_API void TCOD_semaphore_lock(TCOD_semaphore_t sem); TCODLIB_API void TCOD_semaphore_unlock(TCOD_semaphore_t sem); TCODLIB_API void TCOD_semaphore_delete( TCOD_semaphore_t sem); /* condition */ TCODLIB_API TCOD_cond_t TCOD_condition_new(void); TCODLIB_API void TCOD_condition_signal(TCOD_cond_t sem); TCODLIB_API void TCOD_condition_broadcast(TCOD_cond_t sem); TCODLIB_API void TCOD_condition_wait(TCOD_cond_t sem, TCOD_mutex_t mut); TCODLIB_API void TCOD_condition_delete( TCOD_cond_t sem); /* dynamic library */ typedef void *TCOD_library_t; TCODLIB_API TCOD_library_t TCOD_load_library(const char *path); TCODLIB_API void * TCOD_get_function_address(TCOD_library_t library, const char *function_name); TCODLIB_API void TCOD_close_library(TCOD_library_t); /* SDL renderer callback */ #ifdef TCOD_SDL2 typedef void (*SDL_renderer_t) (void *sdl_renderer); TCODLIB_API void TCOD_sys_register_SDL_renderer(SDL_renderer_t renderer); #endif #ifdef __cplusplus } #endif #endif libtcod-1.6.4+dfsg/include/sys.hpp000066400000000000000000000607211321276576200170540ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_SYS_HPP #define _TCOD_SYS_HPP #include "image.hpp" #include "mouse.hpp" #include "sys.h" /** @PageName system @PageCategory Core @PageTitle System layer @PageDesc This toolkit contains some system specific miscellaneous utilities. Use them is you want your code to be easily portable. */ class TCODLIB_API ITCODSDLRenderer { public : virtual ~ITCODSDLRenderer() {} virtual void render(void *sdlSurface) = 0; }; class TCODLIB_API TCODSystem { public : /** @PageName system_time @PageFather system @PageTitle High precision time functions @PageDesc These are functions specifically aimed at real time game development. @FuncTitle Limit the frames per second @FuncDesc The setFps function allows you to limit the number of frames per second. If a frame is rendered faster than expected, the TCOD_console_flush function will wait so that the frame rate never exceed this value. You can call this function during your game initialization. You can dynamically change the frame rate. Just call this function once again. You should always limit the frame rate, except during benchmarks, else your game will use 100% of the CPU power @Cpp static void TCODSystem::setFps(int val) @C void TCOD_sys_set_fps(int val) @Py sys_set_fps(val) @C# static void TCODSystem::setFps(int val) @Lua tcod.system.setFps(val) @Param val Maximum number of frames per second. 0 means unlimited frame rate. */ static void setFps(int val); /** @PageName system_time @FuncTitle Get the number of frames rendered during the last second @FuncDesc The value returned by this function is updated every second. @Cpp static int TCODSystem::getFps() @C int TCOD_sys_get_fps() @Py sys_get_fps() @C# static int TCODSystem::getFps() @Lua tcod.system.getFps() */ static int getFps(); /** @PageName system_time @FuncTitle Get the duration of the last frame @FuncDesc This function returns the length in seconds of the last rendered frame. You can use this value to update every time dependent object in the world. @Cpp static float TCODSystem::getLastFrameLength() @C float TCOD_sys_get_last_frame_length() @Py sys_get_last_frame_length() @C# static float TCODSystem::getLastFrameLength() @Lua tcod.system.getLastFrameLength() @CppEx // moving an objet at 5 console cells per second float x=0,y=0; // object coordinates x += 5 * TCODSystem::getLastFrameLength(); TCODConsole::root->putChar((int)(x),(int)(y),'X'); @CEx float x=0,y=0; x += 5 * TCOD_sys_get_last_frame_length(); TCOD_console_put_char(NULL,(int)(x),(int)(y),'X'); @PyEx x=0.0 y=0.0 x += 5 * libtcod.sys_get_last_frame_length() libtcod.console_put_char(0,int(x),int(y),'X') @LuaEx -- moving an objet at 5 console cells per second x=0 y=0 -- object coordinates x = x + 5 * tcod.system.getLastFrameLength() libtcod.TCODConsole_root:putChar(x,y,'X') */ static float getLastFrameLength(); #ifdef TCOD_OSUTIL_SUPPORT /** @PageName system_time @FuncTitle Pause the program @FuncDesc Use this function to stop the program execution for a specified number of milliseconds. @Cpp static void TCODSystem::sleepMilli(uint32_t val) @C void TCOD_sys_sleep_milli(uint32_t val) @Py sys_sleep_milli(val) @C# static void TCODSystem::sleepMilli(uint val) @Lua tcod.system.sleepMilli(val) @Param val number of milliseconds before the function returns */ static void sleepMilli(uint32_t val); /** @PageName system_time @FuncTitle Get global timer in milliseconds @FuncDesc This function returns the number of milliseconds since the program has started. @Cpp static uint32_t TCODSystem::getElapsedMilli() @C uint32_t TCOD_sys_elapsed_milli() @Py sys_elapsed_milli() @C# static uint TCODSystem::getElapsedMilli() @Lua tcod.system.getElapsedMilli() */ static uint32_t getElapsedMilli(); /** @PageName system_time @FuncTitle Get global timer in seconds @FuncDesc This function returns the number of seconds since the program has started. @Cpp static float TCODSystem::getElapsedSeconds() @C float TCOD_sys_elapsed_seconds() @Py sys_elapsed_seconds() @C# static float TCODSystem::getElapsedSeconds() @Lua tcod.system.getElapsedSeconds() */ static float getElapsedSeconds(); #endif #ifdef TCOD_CONSOLE_SUPPORT /** @PageName console_blocking_input @FuncTitle Waiting for any event (mouse or keyboard) @FuncDesc This function waits for an event from the user. The eventMask shows what events we're waiting for. The return value indicate what event was actually triggered. Values in key and mouse structures are updated accordingly. If flush is false, the function waits only if there are no pending events, else it returns the first event in the buffer. @Cpp typedef enum { TCOD_EVENT_NONE=0, TCOD_EVENT_KEY_PRESS=1, TCOD_EVENT_KEY_RELEASE=2, TCOD_EVENT_KEY=TCOD_EVENT_KEY_PRESS|TCOD_EVENT_KEY_RELEASE, TCOD_EVENT_MOUSE_MOVE=4, TCOD_EVENT_MOUSE_PRESS=8, TCOD_EVENT_MOUSE_RELEASE=16, TCOD_EVENT_MOUSE=TCOD_EVENT_MOUSE_MOVE|TCOD_EVENT_MOUSE_PRESS|TCOD_EVENT_MOUSE_RELEASE, TCOD_EVENT_ANY=TCOD_EVENT_KEY|TCOD_EVENT_MOUSE, } TCOD_event_t; static TCOD_event_t TCODSystem::waitForEvent(int eventMask, TCOD_key_t *key, TCOD_mouse_t *mouse, bool flush) @C TCOD_event_t TCOD_sys_wait_for_event(int eventMask, TCOD_key_t *key, TCOD_mouse_t *mouse, bool flush) @Py sys_wait_for_event(eventMask,key,mouse,flush) @Param eventMask event types to wait for (other types are discarded) @Param key updated in case of a key event. Can be null if eventMask contains no key event type @Param mouse updated in case of a mouse event. Can be null if eventMask contains no mouse event type @Param flush if true, all pending events are flushed from the buffer. Else, return the first available event @CppEx TCOD_key_t key; TCOD_mouse_t mouse; TCOD_event_t ev = TCODSystem::waitForEvent(TCOD_EVENT_ANY,&key,&mouse,true); if ( ev == TCOD_EVENT_KEY_PRESS && key.c == 'i' ) { ... open inventory ... } @CEx TCOD_key_t key; TCOD_mouse_t mouse; TCOD_event_t ev = TCOD_sys_wait_for_event(TCOD_EVENT_ANY,&key,&mouse,true); if ( ev == TCOD_EVENT_KEY_PRESS && key.c == 'i' ) { ... open inventory ... } */ static TCOD_event_t waitForEvent(int eventMask, TCOD_key_t *key, TCOD_mouse_t *mouse, bool flush); /** @PageName console_non_blocking_input @FuncTitle Checking for any event (mouse or keyboard) @FuncDesc This function checks if an event from the user is in the buffer. The eventMask shows what events we're waiting for. The return value indicate what event was actually found. Values in key and mouse structures are updated accordingly. @Cpp typedef enum { TCOD_EVENT_KEY_PRESS=1, TCOD_EVENT_KEY_RELEASE=2, TCOD_EVENT_KEY=TCOD_EVENT_KEY_PRESS|TCOD_EVENT_KEY_RELEASE, TCOD_EVENT_MOUSE_MOVE=4, TCOD_EVENT_MOUSE_PRESS=8, TCOD_EVENT_MOUSE_RELEASE=16, TCOD_EVENT_MOUSE=TCOD_EVENT_MOUSE_MOVE|TCOD_EVENT_MOUSE_PRESS|TCOD_EVENT_MOUSE_RELEASE, TCOD_EVENT_ANY=TCOD_EVENT_KEY|TCOD_EVENT_MOUSE, } TCOD_event_t; static TCOD_event_t TCODSystem::checkForEvent(int eventMask, TCOD_key_t *key, TCOD_mouse_t *mouse) @C TCOD_event_t TCOD_sys_check_for_event(int eventMask, TCOD_key_t *key, TCOD_mouse_t *mouse) @Py sys_check_for_event(eventMask,key,mouse) @Param eventMask event types to wait for (other types are discarded) @Param key updated in case of a key event. Can be null if eventMask contains no key event type @Param mouse updated in case of a mouse event. Can be null if eventMask contains no mouse event type @CppEx TCOD_key_t key; TCOD_mouse_t mouse; TCOD_event_t ev = TCODSystem::checkForEvent(TCOD_EVENT_ANY,&key,&mouse); if ( ev == TCOD_EVENT_KEY_PRESS && key.c == 'i' ) { ... open inventory ... } @CEx TCOD_key_t key; TCOD_mouse_t mouse; TCOD_event_t ev = TCOD_sys_check_for_event(TCOD_EVENT_ANY,&key,&mouse); if ( ev == TCOD_EVENT_KEY_PRESS && key.c == 'i' ) { ... open inventory ... } */ static TCOD_event_t checkForEvent(int eventMask, TCOD_key_t *key, TCOD_mouse_t *mouse); #endif #ifdef TCOD_SDL2 /** @PageName system_screenshots @PageFather system @PageTitle Easy screenshots @FuncDesc This function allows you to save the current game screen in a png file, or possibly a bmp file if you provide a filename ending with .bmp. @Cpp static void TCODSystem::saveScreenshot(const char *filename) @C void TCOD_sys_save_screenshot(const char *filename) @Py sys_save_screenshot(filename) @C# static void TCODSystem::saveScreenshot(string filename); @Lua tcod.system.saveScreenshot(filename) @Param filename Name of the file. If NULL, a filename is automatically generated with the form "./screenshotNNN.png", NNN being the first free number (if a file named screenshot000.png already exist, screenshot001.png will be used, and so on...). */ static void saveScreenshot(const char *filename); #endif /** @PageName system_filesystem @PageFather system @PageTitle Filesystem utilities @PageDesc Those are a few function that cannot be easily implemented in a portable way in C/C++. They have no Python wrapper since Python provides its own builtin functions. All those functions return false if an error occurred. @FuncTitle Create a directory @Cpp static bool TCODSystem::createDirectory(const char *path) @C bool TCOD_sys_create_directory(const char *path) @Param path Directory path. The immediate father directory (/..) must exist and be writable. */ static bool createDirectory(const char *path); /** @PageName system_filesystem @FuncTitle Delete an empty directory @Cpp static bool TCODSystem::deleteDirectory(const char *path) @C bool TCOD_sys_delete_directory(const char *path) @Param path directory path. This directory must exist, be writable and empty */ static bool deleteDirectory(const char *path); /** @PageName system_filesystem @FuncTitle Delete a file @Cpp static bool TCODSystem::deleteFile(const char *path) @C bool TCOD_sys_delete_file(const char *path) @Param path File path. This file must exist and be writable. */ static bool deleteFile(const char *path); /** @PageName system_filesystem @FuncTitle Check if a path is a directory @Cpp static bool TCODSystem::isDirectory(const char *path) @C bool TCOD_sys_is_directory(const char *path) @Param path a path to check */ static bool isDirectory(const char *path); /** @PageName system_filesystem @FuncTitle List files in a directory @FuncDesc To get the list of entries in a directory (including sub-directories, except . and ..). The returned list is allocated by the function and must be deleted by you. All the const char * inside must be also freed with TCODList::clearAndDelete. @Cpp static TCODList TCODSystem::getDirectoryContent(const char *path, const char *pattern) @C TCOD_list_t TCOD_sys_get_directory_content(const char *path) @Param path a directory @Param pattern If NULL or empty, returns all directory entries. Else returns only entries matching the pattern. The pattern is NOT a regular expression. It can only handle one '*' wildcard. Examples : *.png, saveGame*, font*.png */ static TCOD_list_t getDirectoryContent(const char *path, const char *pattern); /** @PageName system_filesystem @FuncTitle Check if a given file exists @FuncDesc In order to check whether a given file exists in the filesystem. Useful for detecting errors caused by missing files. @Cpp static bool TCODSystem::fileExists(const char *filename, ...) @C bool TCOD_sys_file_exists(const char * filename, ...) @Param filename the file name, using printf-like formatting @Param ... optional arguments for filename formatting @CppEx if (!TCODSystem::fileExists("myfile.%s","txt")) { fprintf(stderr,"no such file!"); } @CEx if (!TCOD_sys_file_exists("myfile.%s","txt")) { fprintf(stderr,"no such file!"); } */ static bool fileExists(const char * filename, ...); /** @PageName system_filesystem @FuncTitle Read the content of a file into memory @FuncDesc This is a portable function to read the content of a file from disk or from the application apk (android). buf must be freed with free(buf). @Cpp static bool TCODSystem::readFile(const char *filename, unsigned char **buf, uint32_t *size) @C bool TCOD_sys_read_file(const char *filename, unsigned char **buf, uint32_t *size) @Param filename the file name @Param buf a buffer to be allocated and filled with the file content @Param size the size of the allocated buffer. @CppEx unsigned char *buf; uint32_t size; if (TCODSystem::readFile("myfile.dat",&buf,&size)) { // do something with buf free(buf); } @CEx if (TCOD_sys_read_file("myfile.dat",&buf,&size)) { // do something with buf free(buf); } */ static bool readFile(const char *filename, unsigned char **buf, size_t *size); /** @PageName system_filesystem @FuncTitle Write the content of a memory buffer to a file @FuncDesc This is a portable function to write some data to a file. @Cpp static bool TCODSystem::writeFile(const char *filename, unsigned char *buf, uint32_t size) @C bool TCOD_sys_write_file(const char *filename, unsigned char *buf, uint32_t size) @Param filename the file name @Param buf a buffer containing the data to write @Param size the number of bytes to write. @CppEx TCODSystem::writeFile("myfile.dat",buf,size)); @CEx TCOD_sys_write_file("myfile.dat",buf,size)); */ static bool writeFile(const char *filename, unsigned char *buf, uint32_t size); /** @PageName system_sdlcbk @PageFather system @PageTitle Draw custom graphics on top of the root console @PageDesc You can register a callback that will be called after the libtcod rendering phase, but before the screen buffer is swapped. This callback receives the screen SDL_Surface reference. This makes it possible to use any SDL drawing functions (including openGL) on top of the libtcod console. @FuncTitle Render custom graphics @FuncDesc To disable the custom renderer, call the same method with a NULL parameter. Note that to keep libtcod from requiring the SDL headers, the callback parameter is a void pointer. You have to include SDL headers and cast it to SDL_Surface in your code. @Cpp class TCODLIB_API ITCODSDLRenderer { public : virtual void render(void *sdlSurface) = 0; }; static void TCODSystem::registerSDLRenderer(ITCODSDLRenderer *callback); @C typedef void (*SDL_renderer_t) (void *sdl_surface); void TCOD_sys_register_SDL_renderer(SDL_renderer_t callback) @Py def renderer ( sdl_surface ) : ... TCOD_sys_register_SDL_renderer( callback ) @Param callback The renderer to call before swapping the screen buffer. If NULL, custom rendering is disabled @CppEx class MyRenderer : public ITCODSDLRenderer { public : void render(void *sdlSurface) { SDL_Surface *s = (SDL_Surface *)sdlSurface; ... draw something on s } }; TCODSystem::registerSDLRenderer(new MyRenderer()); @CEx void my_renderer( void *sdl_surface ) { SDL_Surface *s = (SDL_Surface *)sdl_surface; ... draw something on s } TCOD_sys_register_SDL_renderer(my_renderer); @Py def my_renderer(sdl_surface) : ... draw something on sdl_surface using pygame libtcod.sys_register_SDL_renderer(my_renderer) */ static void registerSDLRenderer(ITCODSDLRenderer *renderer); /** @PageName system_sdlcbk @FuncTitle Managing screen redraw @FuncDesc libtcod is not aware of the part of the screen your SDL renderer has updated. If no change occurred in the console, it won't redraw them except if you tell him to do so with this function @Cpp void TCODConsole::setDirty(int x, int y, int w, int h) @C void TCOD_console_set_dirty(int x, int y, int w, int h) @Py TCOD_console_set_dirty(x, y, w, h) @Param x,y,w,h Part of the root console you want to redraw even if nothing has changed in the console back/fore/char. */ #ifdef TCOD_SDL2 /** @PageName system_misc @PageFather system @PageTitle Miscellaneous utilities @FuncTitle Using a custom resolution for the fullscreen mode @FuncDesc This function allows you to force the use of a specific resolution in fullscreen mode. The default resolution depends on the root console size and the font character size. @Cpp static void TCODSystem::forceFullscreenResolution(int width, int height) @C void TCOD_sys_force_fullscreen_resolution(int width, int height) @Py sys_force_fullscreen_resolution(width, height) @C# static void TCODSystem::forceFullscreenResolution(int width, int height); @Lua tcod.system.forceFullscreenResolution(width,height) @Param width,height Resolution to use when switching to fullscreen. Will use the smallest available resolution so that : resolution width >= width and resolution width >= root console width * font char width resolution width >= height and resolution height >= root console height * font char height @CppEx TCODSystem::forceFullscreenResolution(800,600); // use 800x600 in fullscreen instead of 640x400 TCODConsole::initRoot(80,50,"",true); // 80x50 console with 8x8 char => 640x400 default resolution @CEx TCOD_sys_force_fullscreen_resolution(800,600); TCOD_console_init_root(80,50,"",true); @PyEx libtcod.sys_force_fullscreen_resolution(800,600) libtcod.console_init_root(80,50,"",True) @LuaEx tcod.system.forceFullscreenResolution(800,600) -- use 800x600 in fullscreen instead of 640x400 tcod.console.initRoot(80,50,"",true) -- 80x50 console with 8x8 char => 640x400 default resolution */ static void forceFullscreenResolution(int width, int height); /** @PageName system_misc @FuncTitle Get current resolution @FuncDesc You can get the current screen resolution with getCurrentResolution. You can use it for example to get the desktop resolution before initializing the root console. @Cpp static void TCODSystem::getCurrentResolution(int *width, int *height) @C void TCOD_sys_get_current_resolution(int *width, int *height) @Py sys_get_current_resolution() # returns w,h @C# static void TCODSystem::getCurrentResolution(out int w, out int h); @Param width,height contains current resolution when the function returns */ static void getCurrentResolution(int *w, int *h); /** @PageName system_misc @FuncTitle Get fullscreen offset @FuncDesc If the fullscreen resolution does not matches the console size in pixels, black borders are added. This function returns the position in pixels of the console top left corner in the screen. @Cpp static void TCODSystem::getFullscreenOffsets(int *offx, int *offy) @C void TCOD_sys_get_fullscreen_offsets(int *offx, int *offy) @C# static void TCODSystem::getFullscreenOffsets(out int offx, out int offy); @Param offx,offy contains the position of the console on the screen when using fullscreen mode. */ static void getFullscreenOffsets(int *offx, int *offy); /** @PageName system_misc @FuncTitle Get the font size @FuncDesc You can get the size of the characters in the font @Cpp static void TCODSystem::getCharSize(int *width, int *height) @C void TCOD_sys_get_char_size(int *width, int *height) @Py sys_get_char_size() # returns w,h @C# static void TCODSystem::getCharSize(out int w, out int h); @Param width,height contains a character size when the function returns */ static void getCharSize(int *w, int *h); /** @PageName system_misc @FuncTitle Dynamically updating the font bitmap @FuncDesc You can dynamically change the bitmap of a character in the font. All cells using this ascii code will be updated at next flush call. @Cpp static void TCODSystem::updateChar(int asciiCode, int fontx, int fonty,const TCODImage *img,int x,int y) @C void TCOD_sys_update_char(int asciiCode, int fontx, int fonty, TCOD_image_t img, int x, int y) @Py sys_update_char(asciiCode,fontx,fonty,img,x,y) @Param asciiCode ascii code corresponding to the character to update @Param fontx,fonty coordinate of the character in the bitmap font (in characters, not pixels) @Param img image containing the new character bitmap @Param x,y position in pixels of the top-left corner of the character in the image */ static void updateChar(int asciiCode, int fontx, int fonty,const TCODImage *img,int x,int y); #endif #ifdef TCOD_SDL2 /** @PageName system_misc @FuncTitle Dynamically change libtcod's internal renderer @FuncDesc As of 1.5.1, libtcod contains 3 different renderers : * SDL : historic libtcod renderer. Should work and be pretty fast everywhere * OpenGL : requires OpenGL compatible video card. Might be much faster or much slower than SDL, depending on the drivers * GLSDL : requires OpenGL 1.4 compatible video card with GL_ARB_shader_objects extension. Blazing fast if you have the proper hardware and drivers. This function switches the current renderer dynamically. @Cpp static void TCODSystem::setRenderer(TCOD_renderer_t renderer) @C void TCOD_sys_set_renderer(TCOD_renderer_t renderer) @Py sys_set_renderer(renderer) @C# static void TCODSystem::setRenderer(TCODRendererType renderer); @Param renderer Either TCOD_RENDERER_GLSL, TCOD_RENDERER_OPENGL or TCOD_RENDERER_SDL */ static void setRenderer(TCOD_renderer_t renderer); /** @PageName system_misc @FuncTitle Get the current internal renderer @Cpp static TCOD_renderer_t TCODSystem::getRenderer() @C TCOD_renderer_t TCOD_sys_get_renderer() @Py sys_get_renderer() @C# static TCODRendererType TCODSystem::getRenderer(); */ static TCOD_renderer_t getRenderer(); /** @PageName system_clipboard @PageTitle Clipboard integration @PageDesc With these functions, you can copy data in your operating system's clipboard from the game or retrieve data from the clipboard. @PageFather system @FuncTitle Set current clipboard contents @FuncDesc Takes UTF-8 text and copies it into the system clipboard. On Linux, because an application cannot access the system clipboard unless a window is open, if no window is open the call will do nothing. @Cpp static bool TCODSystem::setClipboard(const char *value) @C bool TCOD_sys_clipboard_set(const char *value) @Py sys_clipboard_set(value) @Param value UTF-8 text to copy into the clipboard */ static bool setClipboard(const char *value); /** @PageName system_clipboard @FuncTitle Get current clipboard contents @FuncDesc Returns the UTF-8 text currently in the system clipboard. On Linux, because an application cannot access the system clipboard unless a window is open, if no window is open an empty string will be returned. For C and C++, note that the pointer is borrowed, and libtcod will take care of freeing the memory. @Cpp static char *TCODSystem::getClipboard() @C char *TCOD_sys_clipboard_get() @Py sys_clipboard_get() # Returns UTF-8 string */ static char *getClipboard(); #endif // thread stuff static int getNumCores(); static TCOD_thread_t newThread(int (*func)(void *), void *data); static void deleteThread(TCOD_thread_t th); static void waitThread(TCOD_thread_t th); // mutex static TCOD_mutex_t newMutex(); static void mutexIn(TCOD_mutex_t mut); static void mutexOut(TCOD_mutex_t mut); static void deleteMutex(TCOD_mutex_t mut); // semaphore static TCOD_semaphore_t newSemaphore(int initVal); static void lockSemaphore(TCOD_semaphore_t sem); static void unlockSemaphore(TCOD_semaphore_t sem); static void deleteSemaphore( TCOD_semaphore_t sem); // condition static TCOD_cond_t newCondition(); static void signalCondition(TCOD_cond_t sem); static void broadcastCondition(TCOD_cond_t sem); static void waitCondition(TCOD_cond_t sem, TCOD_mutex_t mut); static void deleteCondition( TCOD_cond_t sem); }; #endif libtcod-1.6.4+dfsg/include/tree.h000066400000000000000000000036331321276576200166340ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_TREE_H #define _TCOD_TREE_H #include "libtcod_portability.h" #ifdef __cplusplus extern "C" { #endif typedef struct _TCOD_tree_t { struct _TCOD_tree_t *next; struct _TCOD_tree_t *father; struct _TCOD_tree_t *sons; } TCOD_tree_t; TCODLIB_API TCOD_tree_t *TCOD_tree_new(void); TCODLIB_API void TCOD_tree_add_son(TCOD_tree_t *node, TCOD_tree_t *son); #ifdef __cplusplus } #endif #endif libtcod-1.6.4+dfsg/include/tree.hpp000066400000000000000000000036741321276576200172010ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_TREE_HPP #define _TCOD_TREE_HPP #include "tree.h" class TCODLIB_API TCODTree { public : TCODTree *next; TCODTree *father; TCODTree *sons; TCODTree() : next(NULL),father(NULL),sons(NULL){} void addSon(TCODTree *data) { data->father=this; TCODTree *lastson = sons; while ( lastson && lastson->next ) lastson=lastson->next; if ( lastson ) { lastson->next=data; } else { sons=data; } } }; #endif libtcod-1.6.4+dfsg/include/txtfield.h000066400000000000000000000051071321276576200175160ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_TEXT_H_ #define _TCOD_TEXT_H_ #include "libtcod_portability.h" #ifdef TCOD_CONSOLE_SUPPORT #include "color.h" #include "console_types.h" #ifdef __cplusplus extern "C" { #endif typedef void * TCOD_text_t; TCODLIB_API TCOD_text_t TCOD_text_init(int x, int y, int w, int h, int max_chars); TCODLIB_API TCOD_text_t TCOD_text_init2(int w, int h, int max_chars); TCODLIB_API void TCOD_text_set_pos(TCOD_text_t txt, int x, int y); TCODLIB_API void TCOD_text_set_properties(TCOD_text_t txt, int cursor_char, int blink_interval, const char * prompt, int tab_size); TCODLIB_API void TCOD_text_set_colors(TCOD_text_t txt, TCOD_color_t fore, TCOD_color_t back, float back_transparency); TCODLIB_API bool TCOD_text_update(TCOD_text_t txt, TCOD_key_t key); TCODLIB_API void TCOD_text_render(TCOD_text_t txt, TCOD_console_t con); TCODLIB_API const char * TCOD_text_get(TCOD_text_t txt); TCODLIB_API void TCOD_text_reset(TCOD_text_t txt); TCODLIB_API void TCOD_text_delete(TCOD_text_t txt); #ifdef __cplusplus } #endif #endif /* TCOD_CONSOLE_SUPPORT */ #endif /* _TCOD_TEXT_H_ */ libtcod-1.6.4+dfsg/include/txtfield.hpp000066400000000000000000000042421321276576200200550ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_TEXT_HPP_ #define _TCOD_TEXT_HPP_ #include "color.hpp" #include "console.hpp" #include "txtfield.h" #ifdef TCOD_CONSOLE_SUPPORT class TCODLIB_API TCODText { public : TCODText(int x, int y, int w, int h, int max_chars); TCODText(int w, int h, int max_chars); ~TCODText(); void setProperties(int cursor_char, int blink_interval, const char * prompt, int tab_size); void setColors(TCODColor fore, TCODColor back, float back_transparency); void setPos(int x, int y); bool update(TCOD_key_t key); void render(TCODConsole * con); const char *getText(); void reset(); protected : TCOD_text_t data; }; #endif /* TCOD_CONSOLE_SUPPORT */ #endif libtcod-1.6.4+dfsg/include/wrappers.h000066400000000000000000000151031321276576200175330ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef WRAPPERS_H #define WRAPPERS_H #include "libtcod_portability.h" #include "console_types.h" #include "image.h" #include "mouse.h" #include "parser.h" #ifdef __cplusplus extern "C" { #endif /* wrappers to ease other languages integration */ typedef unsigned int colornum_t; /* color module */ TCODLIB_API bool TCOD_color_equals_wrapper (colornum_t c1, colornum_t c2); TCODLIB_API colornum_t TCOD_color_add_wrapper (colornum_t c1, colornum_t c2); TCODLIB_API colornum_t TCOD_color_subtract_wrapper (colornum_t c1, colornum_t c2); TCODLIB_API colornum_t TCOD_color_multiply_wrapper (colornum_t c1, colornum_t c2); TCODLIB_API colornum_t TCOD_color_multiply_scalar_wrapper (colornum_t c1, float value); TCODLIB_API colornum_t TCOD_color_lerp_wrapper(colornum_t c1, colornum_t c2, float coef); TCODLIB_API void TCOD_color_get_HSV_wrapper(colornum_t c,float * h, float * s, float * v); TCODLIB_API float TCOD_color_get_hue_wrapper (colornum_t c); TCODLIB_API float TCOD_color_get_saturation_wrapper (colornum_t c); TCODLIB_API float TCOD_color_get_value_wrapper(colornum_t c); #ifdef TCOD_CONSOLE_SUPPORT /* console module */ /* TCODLIB_API void TCOD_console_set_custom_font_wrapper(const char *fontFile, int char_width, int char_height, int nb_char_horiz, int nb_char_vertic, bool chars_by_row, colornum_t key_color); */ TCODLIB_API void TCOD_console_set_default_background_wrapper(TCOD_console_t con, colornum_t col); TCODLIB_API void TCOD_console_set_default_foreground_wrapper(TCOD_console_t con, colornum_t col); TCODLIB_API colornum_t TCOD_console_get_default_background_wrapper(TCOD_console_t con); TCODLIB_API colornum_t TCOD_console_get_default_foreground_wrapper(TCOD_console_t con); TCODLIB_API colornum_t TCOD_console_get_char_background_wrapper(TCOD_console_t con, int x, int y); TCODLIB_API void TCOD_console_set_char_background_wrapper(TCOD_console_t con,int x, int y, colornum_t col, TCOD_bkgnd_flag_t flag); TCODLIB_API colornum_t TCOD_console_get_char_foreground_wrapper (TCOD_console_t con, int x, int y); TCODLIB_API void TCOD_console_set_char_foreground_wrapper(TCOD_console_t con,int x, int y, colornum_t col); TCODLIB_API void TCOD_console_put_char_ex_wrapper(TCOD_console_t con, int x, int y, int c, colornum_t fore, colornum_t back); TCODLIB_API void TCOD_console_set_fade_wrapper(uint8_t val, colornum_t fade); TCODLIB_API colornum_t TCOD_console_get_fading_color_wrapper(void); TCODLIB_API void TCOD_console_set_color_control_wrapper(TCOD_colctrl_t con, colornum_t fore, colornum_t back); TCODLIB_API bool TCOD_console_check_for_keypress_wrapper(TCOD_key_t *holder, int flags); TCODLIB_API void TCOD_console_wait_for_keypress_wrapper(TCOD_key_t *holder, bool flush); TCODLIB_API void TCOD_console_fill_background(TCOD_console_t con, int *r, int *g, int *b); TCODLIB_API void TCOD_console_fill_foreground(TCOD_console_t con, int *r, int *g, int *b); TCODLIB_API void TCOD_console_fill_char(TCOD_console_t con, int *arr); TCODLIB_API void TCOD_console_double_hline(TCOD_console_t con,int x,int y, int l, TCOD_bkgnd_flag_t flag); TCODLIB_API void TCOD_console_double_vline(TCOD_console_t con,int x,int y, int l, TCOD_bkgnd_flag_t flag); TCODLIB_API void TCOD_console_print_double_frame(TCOD_console_t con,int x,int y, int w,int h, bool empty, TCOD_bkgnd_flag_t flag, const char *fmt, ...); TCODLIB_API char *TCOD_console_print_return_string(TCOD_console_t con,int x, int y, int rw, int rh, TCOD_bkgnd_flag_t flag, TCOD_alignment_t align, char *msg, bool can_split, bool count_only); TCODLIB_API void TCOD_console_set_key_color_wrapper (TCOD_console_t con, colornum_t c); #endif #ifdef TCOD_IMAGE_SUPPORT /* image module */ TCODLIB_API void TCOD_image_clear_wrapper(TCOD_image_t image, colornum_t color); TCODLIB_API colornum_t TCOD_image_get_pixel_wrapper(TCOD_image_t image, int x, int y); TCODLIB_API colornum_t TCOD_image_get_mipmap_pixel_wrapper(TCOD_image_t image, float x0,float y0, float x1, float y1); TCODLIB_API void TCOD_image_put_pixel_wrapper(TCOD_image_t image,int x, int y, colornum_t col); TCODLIB_API void TCOD_image_set_key_color_wrapper(TCOD_image_t image, colornum_t key_color); #endif #ifdef TCOD_CONSOLE_SUPPORT /* mouse module */ TCODLIB_API void TCOD_mouse_get_status_wrapper(TCOD_mouse_t *holder); #endif /* parser module */ TCODLIB_API colornum_t TCOD_parser_get_color_property_wrapper(TCOD_parser_t parser, const char *name); /* namegen module */ TCODLIB_API int TCOD_namegen_get_nb_sets_wrapper(void); TCODLIB_API void TCOD_namegen_get_sets_wrapper(char **sets); /* sys module */ TCODLIB_API int TCOD_sys_get_current_resolution_x(void); TCODLIB_API int TCOD_sys_get_current_resolution_y(void); #ifdef __cplusplus } #endif #endif /* WRAPPERS_H */ libtcod-1.6.4+dfsg/include/zip.h000066400000000000000000000066251321276576200165030ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_ZIP_H #define _TCOD_ZIP_H #include "libtcod_portability.h" #include "color.h" #include "console_types.h" #include "image.h" #ifdef __cplusplus extern "C" { #endif typedef void *TCOD_zip_t; TCODLIB_API TCOD_zip_t TCOD_zip_new(void); TCODLIB_API void TCOD_zip_delete(TCOD_zip_t zip); /* output interface */ TCODLIB_API void TCOD_zip_put_char(TCOD_zip_t zip, char val); TCODLIB_API void TCOD_zip_put_int(TCOD_zip_t zip, int val); TCODLIB_API void TCOD_zip_put_float(TCOD_zip_t zip, float val); TCODLIB_API void TCOD_zip_put_string(TCOD_zip_t zip, const char *val); TCODLIB_API void TCOD_zip_put_color(TCOD_zip_t zip, const TCOD_color_t val); #ifdef TCOD_IMAGE_SUPPORT TCODLIB_API void TCOD_zip_put_image(TCOD_zip_t zip, const TCOD_image_t val); #endif #ifdef TCOD_CONSOLE_SUPPORT TCODLIB_API void TCOD_zip_put_console(TCOD_zip_t zip, const TCOD_console_t val); #endif TCODLIB_API void TCOD_zip_put_data(TCOD_zip_t zip, int nbBytes, const void *data); TCODLIB_API uint32_t TCOD_zip_get_current_bytes(TCOD_zip_t zip); TCODLIB_API int TCOD_zip_save_to_file(TCOD_zip_t zip, const char *filename); /* input interface */ TCODLIB_API int TCOD_zip_load_from_file(TCOD_zip_t zip, const char *filename); TCODLIB_API char TCOD_zip_get_char(TCOD_zip_t zip); TCODLIB_API int TCOD_zip_get_int(TCOD_zip_t zip); TCODLIB_API float TCOD_zip_get_float(TCOD_zip_t zip); TCODLIB_API const char *TCOD_zip_get_string(TCOD_zip_t zip); TCODLIB_API TCOD_color_t TCOD_zip_get_color(TCOD_zip_t zip); #ifdef TCOD_IMAGE_SUPPORT TCODLIB_API TCOD_image_t TCOD_zip_get_image(TCOD_zip_t zip); #endif #ifdef TCOD_CONSOLE_SUPPORT TCODLIB_API TCOD_console_t TCOD_zip_get_console(TCOD_zip_t zip); #endif TCODLIB_API int TCOD_zip_get_data(TCOD_zip_t zip, int nbBytes, void *data); TCODLIB_API uint32_t TCOD_zip_get_remaining_bytes(TCOD_zip_t zip); TCODLIB_API void TCOD_zip_skip_bytes(TCOD_zip_t zip, uint32_t nbBytes); #ifdef __cplusplus } #endif #endif libtcod-1.6.4+dfsg/include/zip.hpp000066400000000000000000000277131321276576200170440ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _TCOD_ZIP_HPP #define _TCOD_ZIP_HPP #include "color.hpp" #include "console.hpp" #include "image.hpp" #include "zip.h" /** @PageName zip @PageCategory Base toolkits @PageTitle Compression toolkit @PageDesc This toolkit provides functions to save or read compressed data from a file. While the module is named Zip, it has nothing to do with the .zip format as it uses zlib compression (.gz format). Note that this modules has no Python wrapper. Use Python built-in zip module instead. You can use the compression buffer in two modes: * put data in the buffer, then save it to a file, * load a file into the buffer, then get data from it. */ class TCODLIB_API TCODZip { public : /** @PageName zip_init @PageFather zip @PageTitle Creating a compression buffer @FuncDesc This function initializes a compression buffer. @Cpp TCODZip::TCODZip() @C TCOD_zip_t TCOD_zip_new() */ TCODZip(); /** @PageName zip_init @FuncDesc Once you don't need the buffer anymore, you can release resources. Note that the addresses returned by the getString function are no longer valid once the buffer has been destroyed. @Cpp TCODZip::~TCODZip() @C void TCOD_zip_delete(TCOD_zip_t zip) @Param zip In the C version, the buffer handler, returned by the constructor. @CppEx TCODZip *zip = new TCODZip(); zip->loadFromFile("myCompressedFile.gz"); char c=zip->getChar(); int i=zip->getInt(); float f= zip->getFloat(); const char *s=strdup(zip->getString()); // we duplicate the string to be able to use it after the buffer deletion zip->getData(nbBytes, dataPtr); delete zip; @CEx TCOD_zip_t zip=TCOD_zip_new(); TCOD_zip_load_from_file(zip,"myCompressedFile.gz"); char c=TCOD_zip_get_char(zip); int i=TCOD_zip_get_int(zip); float f=TCOD_zip_get_float(zip); const char *s=strdup(TCOD_zip_get_string(zip)); TCOD_zip_get_data(zip,nbBytes, dataPtr); TCOD_zip_delete(zip); */ ~TCODZip(); /** @PageName zip_put @PageFather zip @PageTitle Using the buffer in output mode @FuncTitle Putting a char in the buffer @Cpp void TCODZip::putChar(char val) @C void TCOD_zip_put_char(TCOD_zip_t zip, char val) @Param zip In the C version, the buffer handler, returned by the constructor. @Param val A 8 bits value to store in the buffer */ void putChar(char val); /** @PageName zip_put @FuncTitle Putting an integer in the buffer @Cpp void TCODZip::putInt(int val) @C void TCOD_zip_put_int(TCOD_zip_t zip, int val) @Param zip In the C version, the buffer handler, returned by the constructor. @Param val An integer value to store in the buffer */ void putInt(int val); /** @PageName zip_put @FuncTitle Putting a floating point value in the buffer @Cpp void TCODZip::putFloat(float val) @C void TCOD_zip_put_float(TCOD_zip_t zip, float val) @Param zip In the C version, the buffer handler, returned by the constructor. @Param val A float value to store in the buffer */ void putFloat(float val); /** @PageName zip_put @FuncTitle Putting a string in the buffer @Cpp void TCODZip::putString(const char *val) @C void TCOD_zip_put_string(TCOD_zip_t zip, const char *val) @Param zip In the C version, the buffer handler, returned by the constructor. @Param val A string to store in the buffer */ void putString(const char *val); /** @PageName zip_put @FuncTitle Putting a color in the buffer @Cpp void TCODZip::putColor(const TCODColor *val) @C void TCOD_zip_put_color(TCOD_zip_t zip, const TCOD_color_t val) @Param zip In the C version, the buffer handler, returned by the constructor. @Param val A color to store in the buffer */ void putColor(const TCODColor *val); #ifdef TCOD_IMAGE_SUPPORT /** @PageName zip_put @FuncTitle Putting an image in the buffer @Cpp void TCODZip::putImage(const TCODImage *val) @C void TCOD_zip_put_image(TCOD_zip_t zip, const TCOD_image_t val) @Param zip In the C version, the buffer handler, returned by the constructor. @Param val An image to store in the buffer */ void putImage(const TCODImage *val); #endif #ifdef TCOD_CONSOLE_SUPPORT /** @PageName zip_put @FuncTitle Putting a console in the buffer @Cpp void TCODZip::putConsole(const TCODConsole *val) @C void TCOD_zip_put_console(TCOD_zip_t zip, const TCOD_console_t val) @Param zip In the C version, the buffer handler, returned by the constructor. @Param val A console to store in the buffer */ void putConsole(const TCODConsole *val); #endif /** @PageName zip_put @FuncTitle Putting some custom data in the buffer @Cpp void TCODZip::putData(int nbBytes, const void *data) @C void TCOD_zip_put_data(TCOD_zip_t zip, int nbBytes, const void *data) @Param zip In the C version, the buffer handler, returned by the constructor. @Param nbBytes Number of bytes to store in the buffer @Param val Address of the data to store in the buffer */ void putData(int nbBytes, const void *data); /** @PageName zip_put @FuncTitle Reading the number of (uncompressed) bytes in the buffer @Cpp uint32_t TCODZip::getCurrentBytes() @C uint32_t TCOD_zip_get_current_bytes(TCOD_zip_t zip) @Param zip In the C version, the buffer handler, returned by the constructor. */ uint32_t getCurrentBytes() const; /** @PageName zip_put @FuncTitle Saving the buffer on disk @FuncDesc Once you have finished adding data in the buffer, you can compress it and save it in a file. The function returns the number of (uncompressed) bytes saved. @Cpp int TCODZip::saveToFile(const char *filename) @C int TCOD_zip_save_to_file(TCOD_zip_t zip, const char *filename) @Param zip In the C version, the buffer handler, returned by the constructor. @Param filename Name of the file @CppEx TCODZip zip; zip.putChar('A'); zip.putInt(1764); zip.putFloat(3.14f); zip.putString("A string"); zip.putData(nbBytes, dataPtr); zip.saveToFile("myCompressedFile.gz"); @CEx TCOD_zip_t zip=TCOD_zip_new(); TCOD_zip_put_char(zip,'A'); TCOD_zip_put_int(zip,1764); TCOD_zip_put_float(zip,3.14f); TCOD_zip_put_string(zip,"A string"); TCOD_zip_put_data(zip,nbBytes, dataPtr); TCOD_zip_save_to_file(zip,"myCompressedFile.gz"); */ int saveToFile(const char *filename); /** @PageName zip_load @PageTitle Using the buffer in input mode @PageFather zip @FuncTitle Reading from a compressed file @FuncDesc You can read data from a file (compressed or not) into the buffer. The function returns the number of (uncompressed) bytes read or 0 if an error occurred. @Cpp int TCODZip::loadFromFile(const char *filename) @C int TCOD_zip_load_from_file(TCOD_zip_t zip, const char *filename) @Param zip In the C version, the buffer handler, returned by the constructor. @Param filename Name of the file */ int loadFromFile(const char *filename); /** @PageName zip_load @FuncTitle Reading a char from the buffer @Cpp char TCODZip::getChar() @C char TCOD_zip_get_char(TCOD_zip_t zip) @Param zip In the C version, the buffer handler, returned by the constructor */ char getChar(); /** @PageName zip_load @FuncTitle Reading an integer from the buffer @Cpp int TCODZip::getInt() @C int TCOD_zip_get_int(TCOD_zip_t zip) @Param zip In the C version, the buffer handler, returned by the constructor. */ int getInt(); /** @PageName zip_load @FuncTitle Reading a floating point value from the buffer @Cpp float TCODZip::getFloat() @C float TCOD_zip_get_float(TCOD_zip_t zip) @Param zip In the C version, the buffer handler, returned by the constructor. */ float getFloat(); /** @PageName zip_load @FuncTitle Reading a string from the buffer @FuncDesc The address returned is in the buffer. It is valid as long as you don't destroy the buffer. @Cpp const char *TCODZip::getString() @C const char *TCOD_zip_get_string(TCOD_zip_t zip) @Param zip In the C version, the buffer handler, returned by the constructor. */ const char *getString(); /** @PageName zip_load @FuncTitle Reading a color from the buffer @Cpp TCODColor TCODZip::getColor() @C TCOD_color_t TCOD_zip_get_color(TCOD_zip_t zip) @Param zip In the C version, the buffer handler, returned by the constructor. */ TCODColor getColor(); #ifdef TCOD_IMAGE_SUPPORT /** @PageName zip_load @FuncTitle Reading a color from the buffer @Cpp TCODImage *TCODZip::getImage() @C TCOD_image_t TCOD_zip_get_image(TCOD_zip_t zip) @Param zip In the C version, the buffer handler, returned by the constructor. */ TCODImage *getImage(); #endif #ifdef TCOD_CONSOLE_SUPPORT /** @PageName zip_load @FuncTitle Reading a console from the buffer @Cpp TCODConsole *TCODZip::getConsole() @C TCOD_console_t TCOD_zip_get_console(TCOD_zip_t zip) @Param zip In the C version, the buffer handler, returned by the constructor. */ TCODConsole *getConsole(); #endif /** @PageName zip_load @FuncTitle Reading some custom data from the buffer @FuncDesc Note that the getData length must match the length of the data when the file was created (with putData). The function returns the number of bytes that were stored in the file by the putData call. If more than nbBytes were stored, the function read only nbBytes and skip the rest of them. @Cpp int TCODZip::getData(int nbBytes, void *data) @C int TCOD_zip_get_data(TCOD_zip_t zip, int nbBytes, void *data) @Param zip In the C version, the buffer handler, returned by the constructor. @Param nbBytes Number of bytes to read @Param data Address of a pre-allocated buffer (at least nbBytes bytes) @CppEx TCODZip zip; zip.loadFromFile("myCompressedFile.gz"); char c=zip.getChar(); int i=zip.getInt(); float f= zip.getFloat(); const char *s=zip.getString(); zip.getData(nbBytes, dataPtr); @CEx TCOD_zip_t zip=TCOD_zip_new(); TCOD_zip_load_from_file(zip,"myCompressedFile.gz"); char c=TCOD_zip_get_char(zip); int i=TCOD_zip_get_int(zip); float f=TCOD_zip_get_float(zip); const char *s=TCOD_zip_get_string(zip); TCOD_zip_get_data(zip,nbBytes, dataPtr); */ int getData(int nbBytes, void *data); /** @PageName zip_load @FuncTitle Getting the number of remaining bytes in the buffer @Cpp uint32_t TCODZip::getRemainingBytes() const @C uint32_t TCOD_zip_get_remaining_bytes(TCOD_zip_t zip) @Param zip In the C version, the buffer handler, returned by the constructor. */ uint32_t getRemainingBytes() const; /** @PageName zip_load @FuncTitle Skipping some bytes in the buffer @Cpp void TCODZip::skipBytes(uint32_t nbBytes) @C void TCOD_zip_skip_bytes(TCOD_zip_t zip, uint32_t nbBytes) @Param zip In the C version, the buffer handler, returned by the constructor. @Param nbBytes number of uncompressed bytes to skip */ void skipBytes(uint32_t nbBytes); protected : TCOD_zip_t data; }; #endif libtcod-1.6.4+dfsg/libtcod-CHANGELOG.txt000066400000000000000000001127541321276576200175540ustar00rootroot00000000000000X API break + new features % modified features - removed features, fixed bugs This project does not adhere to Semantic Versioning. http://semver.org/ ========================================================= 1.6.5 : Unreleased ========================================================= 1.6.4 : 2017-11-27 + Added support for loading/saving REXPaint files. (Kyle Stewart) % Upgraded to `stdint.h` source code typing via `pstdint.h` (rmtew) https://bitbucket.org/libtcod/libtcod/issues/91 % All libtcod headers are now self-contained. (Kyle Stewart) https://bitbucket.org/libtcod/libtcod/issues/93/header-organization % bool type is now based off of stdbool.h (Kyle Stewart) % SCons builder defaults to debug builds, now builds with OpenGL, and uses link time optimization on release builds. (Kyle Stewart) https://bitbucket.org/libtcod/libtcod/issues/92/tcod_renderer_glsl-not-working % Text input events now include correct modifier key values. (Kyle Stewart) % Fixed touch support compilation, although it is still an experimental option that may change (rmtew) - Console objects should be safe to create and use before libtcod is fully initialized. (Kyle Stewart) https://bitbucket.org/libtcod/libtcod/issues/17/offline-libtcod - Added documentation to guide people in upgrading from 1.5.x to 1.6.x (rmtew) https://bitbucket.org/libtcod/libtcod/issues/88 - Fixed TCOD_list_reverse. (Kyle Stewart) - Fixed simplex noise artifacts when using negative coordinates. (Kyle Stewart) - Fixed the GLSL and OPENGL renderers on all platforms. (rmtew) (Kyle Stewart) https://bitbucket.org/libtcod/libtcod/issues/92/tcod_renderer_glsl-not-working - TCOD_image_blit_2x no longer alters a consoles default colors. (Kyle Stewart) - SDL is no longer initialized at module load time. (Kyle Stewart) https://bitbucket.org/libtcod/libtcod/issues/107/sdl_init-on-library-load-libtcod - SDL renderer is only created when using SDL rendering (wump@bitbucket) https://bitbucket.org/libtcod/libtcod/pull-requests/74/dont-create-sdl-renderer-when-using-opengl ========================================================= 1.6.3 : 2017-02-26 + Added SCons build support (HexDecimal@bitbucket). https://bitbucket.org/libtcod/libtcod/commits/92c5a1b530049f15d1ed36375b12781554272f17 + Exposed clipboard API to Python (rmtew@bitbucket). + Added TravisCI integration tests (Kyle Stewart) https://bitbucket.org/libtcod/libtcod/pull-requests/61 + Added .gitattributes and .gitignore files (Kyle Stewart) https://bitbucket.org/libtcod/libtcod/pull-requests/61 % Updated restrictive FOV code to match MRPAS v1.2 (mingos@bitbucket) https://bitbucket.org/libtcod/libtcod/commits/28a19912ac7fef6e68164fb8970230517888c9ff % Per-platform clipboard get/set code has been removed, and the SDL2 API is used instead (rmtew@bitbucket). The clipboard encoding is now UTF-8 on all platforms. https://bitbucket.org/libtcod/libtcod/issues/81/ % Documented and undeprecated TCOD_mouse_get_status() as the state is awkwardly exposed via check/wait event calls anyway (rmtew@bitbucket). % Switched Python tests to use pytest instead of unittest. (Kyle Stewart) https://bitbucket.org/libtcod/libtcod/pull-requests/61 - TCOD_path_walk now considers negative values to be blocking the path (HexDecimal@bitbucket) https://bitbucket.org/libtcod/libtcod/commits/fc8c88ec9b5d7b113ba3a7906f526daba81b543c - Fix key handling in name generator in C sample (reported by Chris Hamons@bitbucket) https://bitbucket.org/libtcod/libtcod/issues/83/ - Fix for broken SDL callback (reported by grimstain@bitbucket) https://bitbucket.org/libtcod/libtcod/issues/78/sdl-callback-null-pixels - Fix for memory leak introduced with the foreground/background image change (Aaron Wise). https://bitbucket.org/libtcod/libtcod/commits/275e8bd97000599e9d87bfa138fa72c066b1cae7 - Fix for bug in Slider::setFormat() which left a dangling pointer (reported by Kai Kratz@bitbucket) https://bitbucket.org/libtcod/libtcod/commits/07c1214077d121107c5ad8ee38c589ad677f5e76 - Fix potential wavelet related memory leak in TCOD_noise_delete() (HexDecimal@bitbucket) https://bitbucket.org/libtcod/libtcod/commits/a03a79814fd734e05e5d72801376b2af6b315373 - Fix libtcodpy return type for TCOD_console_put_char_ex and TCOD_console_put_char (HexDecimal@bitbucket) https://bitbucket.org/libtcod/libtcod/commits/a03a79814fd734e05e5d72801376b2af6b315373 - Fix libtcodpy arguments for TCOD_heightmap_add_fbm and TCOD_heightmap_scale_fbm (HexDecimal@bitbucket) https://bitbucket.org/libtcod/libtcod/commits/6f34ffa3d17af39cc274c048ff633be8609998f8 - Fixed creating a libtcodpy pathfinder with a callback would crash on 64-bit Unix systems (Kyle Stewart) https://bitbucket.org/libtcod/libtcod/pull-requests/61 ========================================================= 1.6.2 : 2016-12-28 + doctcod command added to VS2015 solution. + Python (PTVS) project for samples_py added to VS2015 solution. + Console foreground and background colours are images. https://bitbucket.org/libtcod/libtcod/issues/51/console-image-unification + Python unit tests added (Kyle Stewart). https://bitbucket.org/libtcod/libtcod/commits/7a66ad5d66832686c0071e3938b85ebad8e7cebb + Added TCOD_console_get_background_color_image and TCOD_console_get_foreground_color_image API for C++/C/Python. % crash bugs fixed in documentation generation. % libtcodpy when loading a DLL now explicitly compares the architecture of the Python version uses, to the architecture of the DLL and exits outputting any difference. % libtcodpy now uses more wrapper functions on Windows to cover ctypes limitations in passing and returning struct values. % libtcodpy now inlines more ctypes argtypes and restype definitions in order to work better on x64. % libtcodpy partially rewritten to support Python 3 as best possible and resolve outstanding 64 bit problems. % samples_py partially rewritten to run under both Python 3 and Python 2. % C++ TCODParser memory leak fixed. https://bitbucket.org/libtcod/libtcod/issues/27/tcodparser-memory-leaks % Adopted strict prototypes / void in C parameterless functions (Kyle Stewart). https://bitbucket.org/libtcod/libtcod/commits/5353098a70254b59b740865a875cccf1d6d84c27 % Frost sample fixed for a non-initialised data structure crash. % SDL2 supported revision updated to release-2.0.5 AKA changeset 007dfe83abf8. X Removed SDL1 support. X Removed C/C++/Python API functions TCOD_sys_set_keyboard_repeat and TCOD_sys_disable_keyboard_repeat. This was SDL1 functionality, and not supported in SDL2. ========================================================= 1.6.1 : 2016 Sep 23 % Python libtcodpy is now better at finding DLLs on Windows https://bitbucket.org/libtcod/libtcod/commits/eda0075 ========================================================= 1.6.0 : 2016 Sep 16 + added support for autotools builds https://bitbucket.org/libtcod/libtcod/commits/41e1c24 + added support for Visual Studio builds + added Visual Studio build script that can fetch and build dependencies, the project, and package up the result + hooked up Visual Studio build script to continuous integration service to run on each commit + libtcod is now reentrant which allows the window to be resized among other things https://bitbucket.org/libtcod/libtcod/commits/14bad22 + added new TCODK_TEXT event to cover the SDL2 SDL_TEXTINPUT event. https://bitbucket.org/libtcod/libtcod/commits/7a8b072 % upgraded to SDL2 % upgraded zlib to version 1.2.8 % upgraded lodepng to the 20160501 release https://bitbucket.org/libtcod/libtcod/commits/60c127e % fixed compilation warnings in pathing code https://bitbucket.org/libtcod/libtcod/commits/4045633 % fixed memory leaks in pathing (Paral Zsolt) https://bitbucket.org/libtcod/libtcod/commits/4c4af80 % lmeta and rmeta modifiers have been added to TCOD_key_t https://bitbucket.org/libtcod/libtcod/commits/e386362 % map numlock key for SDL2 https://bitbucket.org/libtcod/libtcod/commits/83d481c % reset the cursor in text field when the text field is reset (cottog) https://bitbucket.org/libtcod/libtcod/commits/6673e6c % remove superfluous calls to SDL_PumpEvents https://bitbucket.org/libtcod/libtcod/commits/1edf96d % alt-tabbing back to the libtcod window would leave the window blank https://bitbucket.org/libtcod/libtcod/commits/73fdf51 - removed support for mingw builds because no-one could get it to work ========================================================= 1.5.2 : ? + added mid point displacement algorithm to the heightmap toolkit + added TCODConsole::hasMouseFocus() and TCODConsole::isActive() + added TCODParser::hasProperty to check if a property is defined when using the default parser + added TCODText::setPos(int x, int y) - fixed TCODConsole::waitForKeypress returning for both press and release events (returns only on press) - fixed dynamic font switching not working - fixed TCOD_image_blit_rect not working with odd width/height - fixed TCODK_RWIN/TCODK_LWIN not detected - fixed TCOD_sys_wait_event not returning on mouse events - fixed mouse dcx/dcy fields always 0 when the cursor moves slowly - fixed crash in Python console_map_ascii_codes_to_font ========================================================= 1.5.1 : 2012 Aug 29 X TCOD_console_wait_for_keypress, TCOD_console_check_for_keypress, TCOD_mouse_get_status replaced with TCOD_sys_check_for_event and TCOD_sys_wait_for_event X source width and height can be 0 in TCODConsole::blit to blit the whole console X Some of the parser-related functions now can be chained. X The RNG API now has less functions that choose the distribution based on the set flags. X The noise API now has less functions that choose the noise type based on the set flags. X Console default and cell foreground and background colour getters and setters renamed to more intuitive names: * TCOD_console_set_background_color => TCOD_console_set_default_background * TCOD_console_set_foreground_color => TCOD_console_set_default_foreground * TCOD_console_get_background_color => TCOD_console_get_default_background * TCOD_console_get_foreground_color => TCOD_console_get_default_foreground * TCOD_console_set_back => TCOD_console_set_char_background * TCOD_console_set_fore => TCOD_console_set_char_foreground * TCOD_console_get_back => TCOD_console_get_char_background * TCOD_console_get_fore => TCOD_console_get_char_foreground * setBackgroundColor => setDefaultBackground * setForegroundColor => setDefaultForeground * getBackgroundColor => getDefaultBackground * getForegroundColor => getDefaultForeground * setBack => setCharBackground * setFore => setCharForeground * getBack => getCharBackground * getFore => getCharForeground X TCODConsole::printLeft/Right/Center replaced by TCODConsole::setBackgroundFlag(TCOD_bkgnd_flag_t) TCODConsole::setAlignment(TCOD_alignment_t) TCODConsole::print(int x, int y, const char *fmt, ...) TCODConsole::printEx(int x, int y, TCOD_bkgnd_flag_t bkgnd, TCOD_alignment_t alignment, const char *fmt, ...) added TCOD_BKGND_DEFAULT as default value in rect / putChar / hline / vline / setBack the default background flag for a console is BKGND_NONE Warning ! That mean the rect/putChar/... functions now default to BKGND_NONE instead of BKGND_SET, except if you call setBackgroundFlag before using them. X TCODConsole::getHeightLeft/Right/CenterRect replaced by TCODConsole::getHeightRect(int x, int y, int w, int h, const char *fmt, ...); (the 3 functions were useless, the height does not depend on the alignement... X( ) X TCODConsole::initRoot has an additional renderer parameter : static void TCODConsole::initRoot(int w, int h, const char * title, bool fullscreen = false, TCOD_renderer_t renderer=TCOD_RENDERER_SDL); Possible values : TCOD_RENDERER_GLSL, TCOD_RENDERER_OPENGL or TCOD_RENDERER_SDL X TCODMap::clear now sets walkable and transparent status of all cells: void TCODMap::clear (bool transparent = false, bool walkable = false) void TCOD_map_clear (TCOD_map_t map, bool transparent, bool walkable) map_clear (map, transparent, walkable) + cmake compilation works on FreeBSD thanks to namor_ + added support for python3k. The samples run with Python 3.2.3 + added support for colored tiles. Standard font characters MUST only use greyscale colors. + added native support for .ASC and .APF file (Ascii Paint format) * TCODConsole::TCODConsole(const char *filename) * bool TCODConsole::loadAsc(const char *filename) * bool TCODConsole::saveAsc(const char *filename) const * bool TCODConsole::loadApf(const char *filename) * bool TCODConsole::saveApf(const char *filename) const + added mouse wheel support in TCOD_mouse_t.wheel_up/wheel_down + added TCODSystem::fileExists function for checking whether a given file exists + added dice to the TCODRandom toolkit + added support for dynamic property declaration in the parser + added TCODList::reverse(), TCODPath::reverse(), TCODDijkstra::reverse() + added weighted Gaussian distribution RNG + added Gaussian distribution RNG with no minimum/maximum bounds (using only mean and standard deviance) + added clipboard support in TCODSystem (on Linux, only X clipboard supported) + added GLSL and OpenGL(fixed pipeline) renderer (FPS increased 880% on true color sample !!!) + added libtcod.cfg (allows the player to tweaks libtcod overriding the game presets) + added more TCOD_CHAR_* constants + added TCODColor::scaleHSV (saturation and value scaling) + added TCODColor::shiftHue (hue shifting up and down) + added a TCODColor constructor for HSV values + added TCODColor H, S and V separate getters and setters + added TCODColor::rotate90 + added native Mac OSX support + added support for quote-less HTML color values in the parser (col=#FFFFFF instead of col="#FFFFFF") + added color control helpers for C# (TCODConsole.getColorControlString/getRGBColorControlString) % Restrictive FOV algo updated to MRPAS v1.1 (faster, better-looking, improved symmetry) % Gaussian distribution in TCODRandom now uses a more precise Box-Muller transform algorithm % More default values for printFrame : void printFrame(int x,int y,int w,int h, bool clear=true, TCOD_bkgnd_flag_t flag = TCOD_BKGND_DEFAULT, const char *fmt=NULL, ...) % hardened fov module % extended list of colour constants (the old names can produce slightly different colours) % TCODMap memory consumption divided by 4 % now mouse wheel events are properly detected - fixed namegen crash if generator list is empty - fixed permissive fov when light_walls is false - fixed possible crash when clearing an offscreen console before calling initRoot - fix possible crash when printing a string containing ascii codes > 127 - fixed TCODNamegen returning integers in the Python version - fixed TCODDijkstra segfault when diagonal movement cost was zero - fixed setDirty() not working for the last row or column of the console - fixed Python samples not compiling if numpy installed - fixed Python TCOD_parser_get_list_property - fixed TCODDijkstra destructor crash bug - fixed TCODColor::setHSV bug when using hues below 0 or above 359 grades - fixed some rare issues in A* pathfinding - fixed issue in TCODImage::blit2x when blitting only a subregion of the image - fixed memory leak in TCODImage::save ========================================================= 1.5.0 : 2010 Feb 15 X TCODRandom::getIntFromByteArray has been deleted X the random number generator module now support two algorithms (Mingos) Mersenne twister, used in previous versions of libtcod Complementary Multiply With Carry, 2 to 3 times faster and has a much better period. This is the default algo. You can choose the algorithm in the constructor : typedef enum { TCOD_RNG_MT, TCOD_RNG_CMWC } TCOD_random_algo_t; TCODRandom() => CMWC, default seed TCODRandom(uint32 seed) => CMWC, custom seed TCODRandom(TCOD_random_algo_t algo) => default seed, custom algo TCODRandom(uint32 seed, TCOD_random_algo_t aldo) => custom algo and seed X removed bitfield from TCOD_key_t and TCOD_mouse_t to ease wrappers writing. existing working wrappers might be broken, though. X TCODConsole::printFrame now takes an extra argument: TCOD_bkgnd_flag_t X renamed libraries on Linux to improve portability : libtcod++.so => libtcodxx.so libtcod-gui.so => libtcodgui.so + added text field toolkit (undocumented) + added functions for fast Python full console coloring: console_fill_foreground(con,r,g,b) console_fill_background(con,r,g,b) r,g,b are 1D arrays of console_width * console_height + added fast Python rendering sample (Jotaf) + added TCODConsole::resetCredits() to restart credits animation before it's finished + added TCODConsole::setDirty(int x, int y, int w,int h) to force libtcod to redraw a part of the console This might by needed when using the SDL renderer + added TCODSystem::getCharSize(int *w, int *h) to get the current font's character size + added name generation module (Mingos) + added Dijkstra pathfinding (Mingos) + added approximated gaussian distribution functions in the RNG module float TCODRandom::getGaussian(float min, float max) + added subcell resolution blitting function TCODImage::blit2x + added more portable filesystem utilities : static bool TCODSystem::isDirectory(const char *path) static TCODList TCODSystem::getDirectoryContent(const char *path, const char *pattern) + added TCODConsole::putCharEx(int x, int y, int c, TCODColor &fore, TCODColor &back) (at last!) + added waitThread and thread conditions support in (undocumented) threading API + added unicode support and 4 unicode fonts courtesy of Mingos. Functions with unicode support are : static void TCODConsole::mapStringToFont(const wchar_t *s, int fontCharX, int fontCharY); void TCODConsole::printLeft(int x, int y, TCOD_bkgnd_flag_t flag, const wchar_t *fmt, ...); void TCODConsole::printRight(int x, int y, TCOD_bkgnd_flag_t flag, const wchar_t *fmt, ...); void TCODConsole::printCenter(int x, int y, TCOD_bkgnd_flag_t flag, const wchar_t *fmt, ...); int TCODConsole::printLeftRect(int x, int y, int w, int h, TCOD_bkgnd_flag_t flag, const wchar_t *fmt, ...); int TCODConsole::printRightRect(int x, int y, int w, int h, TCOD_bkgnd_flag_t flag, const wchar_t *fmt, ...); int TCODConsole::printCenterRect(int x, int y, int w, int h, TCOD_bkgnd_flag_t flag, const wchar_t *fmt, ...); int TCODConsole::getHeightLeftRect(int x, int y, int w, int h, const wchar_t *fmt, ...); int TCODConsole::getHeightRightRect(int x, int y, int w, int h, const wchar_t *fmt, ...); int TCODConsole::getHeightCenterRect(int x, int y, int w, int h,const wchar_t *fmt, ...); C versions of the functions have _utf suffixes. Unicode fonts are : fonts/consolas_unicode_10x10.png fonts/consolas_unicode_12x12.png fonts/consolas_unicode_16x16.png fonts/consolas_unicode_8x8.png % new compilation system with a debug and release version of the library % makefiles have been moved to a makefiles subdirectory % libtcod credits now use subcell resolution - fixed wrong ascii code returned by check/waitForKeypress with AltGr+0-9 combination - fixed RNG going mad if you delete the default RNG - fixed wait_for_keypress not working in Python - now the parser can handle strings/identifiers with unlimited size (previously limited to 256 chars) - fixed TCODZip module missing from MSVC release - fixed issue with TCOD_COLCTRL_FORE_RGB and TCOD_COLCTRL_BACK_RGB when using 10 or 37 in rgb values - fixed issue in color_set_hsv Python wrapper - fixed bug in console blitting when destination coordinates are outside the destination console ========================================================= 1.4.2 : 2009 Oct 06 X TCODConsole::blit now takes 2 float parameters : static void blit(const TCODConsole *src,int xSrc, int ySrc, int wSrc, int hSrc, TCODConsole *dst, int xDst, int yDst, float foreground_alpha=1.0f, float background_alpha=1.0f) + added possibility to use SDL drawing functions on top of the root console with TCODSystem::registerSDLRenderer + added Mingos' restrictive precise angle shadowcasting fov algorithm as FOV_RESTRICTIVE + heightmap : added missing TCOD_heightmap_set_value function + new consolas, dejavu, lucida and prestige fonts from Mingos - fixed R/B inversion in color operations in Python - fixed a crash when saving a TCODImage before initializing the root console - fixed a crash when destroying an empty TCODZip (file not found) - fixed torch effect in C++ sample - fixed ASCII_IN_ROW flag not working - fixed path_new_using_function not working in Python wrapper - fixed alignment issues in TCOD_console_print_* with strings containing ascii codes > 127 - fixed color controls not working with autowrap - fixed fov post-processing step to handle opaque walkable cells (for example bush) ========================================================= 1.4.1 : 2009 Mar 22 X Default colors have been changed/added. X TCODMap::computeFov changed to support several algorithms : void computeFov(int playerX,int playerY, int maxRadius,bool light_walls = true, TCOD_fov_algorithm_t algo = FOV_BASIC) available algorithms : FOV_BASIC : classic libtcod fov FOV_DIAMOND : http://www.geocities.com/temerra/los_rays.html FOV_SHADOW : http://roguebasin.roguelikedevelopment.org/index.php?title=FOV_using_recursive_shadowcasting FOV_PERMISSIVE : http://roguebasin.roguelikedevelopment.org/index.php?title=Precise_Permissive_Field_of_View light_walls : if false, wall cells are not put in the fov X setCustomFont changed : defines the font number of characters instead of character size if not specified, it is deduced from the layout flag (16x16 for ascii, 32x8 for tcod) setCustomFont(const char *fontFile, int flags=TCOD_FONT_LAYOUT_ASCII_INCOL,int nbCharHoriz=0, int nbCharVertic=0) The flag values have changed too: TCOD_FONT_LAYOUT_ASCII_INCOL=1, TCOD_FONT_LAYOUT_ASCII_INROW=2, TCOD_FONT_TYPE_GREYSCALE=4, TCOD_FONT_TYPE_GRAYSCALE=4, TCOD_FONT_LAYOUT_TCOD=8, + added Python wrapper + added arial, courier fonts courtesy of Mingos + added some non portable filesystem utilities in TCODSystem : bool TCODSystem::createDirectory(const char *path); bool TCODSystem::deleteDirectory(const char *path); bool TCODSystem::deleteFile(const char *path); + added multithread utilities in TCODSystem : static TCOD_thread_t TCODSystem::newThread(int (*func)(void *), void *data); static void TCODSystem::deleteThread(TCOD_thread_t th); static TCOD_mutex_t TCODSystem::newMutex(); static void TCODSystem::mutexIn(TCOD_mutex_t mut); static void TCODSystem::mutexOut(TCOD_mutex_t mut); static void TCODSystem::deleteMutex(TCOD_mutex_t mut); static TCOD_semaphore_t TCODSystem::newSemaphore(int initVal); static void TCODSystem::lockSemaphore(TCOD_semaphore_t sem); static void TCODSystem::unlockSemaphore(TCOD_semaphore_t sem); static void TCODSystem::deleteSemaphore( TCOD_semaphore_t sem); + added some image utilities : void TCODImage::clear(const TCODColor col) void TCODImage::invert() void TCODImage::hflip() void TCODImage::vflip() void TCODImage::scale(int neww, int newh) void TCODImage::setKeyColor(const TCODColor keyColor) int TCODImage::getAlpha(int x,int y) const bool TCODImage::isPixelTransparent(int x, int y) const + can now dynamically modify the content of the font bitmap : static void TCODSystem::updateChar(int asciiCode, int fontx, int fonty,const TCODImage *img,int x,int y) + added C and Python code generation in the heightmap tool + added function to calculate the height of a printed string (with autowrapping) without actually printing it : int TCODConsole::getHeightLeftRect(int x, int y, int w, int h, const char *fmt, ...) int TCODConsole::getHeightRightRect(int x, int y, int w, int h, const char *fmt, ...) int TCODConsole::getHeightCenterRect(int x, int y, int w, int h, const char *fmt, ...) + parser : now strings properties can be split. The parser concatenates them : myProperty = "string value can use " "multi line layout" + parser : added missing getCharProperty when using default listener + heightmap : added missing TCOD_heightmap_get_value function + now support fonts with unlimited number of characters (was limited to 1024 in 1.4.0) + added callback-based atomic bresenham function static bool TCODLine::line(int xFrom, int yFrom, int xTo, int yTo, TCODLineListener *listener) + added TCODMap::copy function + added TCODList fast remove functions (don't preserve the list order) template void TCODList::removeFast(const T elt) template T * TCODList::removeFast(T *elt) % pathfinding : you don't need to provide coordinates in x,y parameters of Path::walk % improved double/simple walls special characters in tcod layout fonts - fixed SDL dependent features not being available before initRoot is called. If you want to draw on an offscreen console without calling initRoot, you need to call at least setCustomFont to initialize the font. Else characters won't be rendered. - fixed standalone credits page erasing previously fps limit - fixed special characters TCOD_CHAR_DTEE* and TCOD_CHAR_DCROSS not printing correctly - fixed heightmap tool generated code not compiling - fixed parser C++ error function not prepending file name & line number to the error message - fixed memory leak in pathfinding - fixed fov issue with walkable, non transparent cells - fixed numerical stability issues with heightmap rain erosion - fixed calculation error in heightmap kernel transformation function - fixed TCODConsole::renderCredits being able to render the credits only once - fixed mouse cx,cy coordinates in "padded" fullscreen modes - fixed mouse cursor hidden when switching fullscreen - fixed mouse coordinates when going fullscreen->windowed ========================================================= 1.4.0 : 2008 Oct 16 X Noise functions renamed : TCODNoise::getNoise -> TCODNoise::getPerlin TCODNoise::getFbm -> TCODNoise::getFbmPerlin TCODNoise::getTurbulence -> TCODNoise::getTurbulencePerlin X Some special char constants (TCOD_CHAR_xxx) added/removed X setCustomFont changed : setCustomFont(const char *fontFile,int charWidth=8, int charHeight=8, int flags=0) flags : TCOD_FONT_LAYOUT_ASCII_INROW=1 TCOD_FONT_TYPE_GREYSCALE=2 TCOD_FONT_LAYOUT_TCOD=4 + added pathfinding module + added BSP module + added heightmap module + heightmap tool + added compression toolkit + added possibility to pre-allocate TCODList's memory + added support for PNG images + antialiased fonts from PNG with alpha channel or greyscale + added ASCII mapping functions to map an ascii code to any character in your font : static void TCODConsole::mapAsciiCodeToFont(int asciiCode, int fontCharX, int fontCharY); static void TCODConsole::mapAsciiCodesToFont(int firstAsciiCode, int nbCodes, int fontCharX, int fontCharY); static void TCODConsole::mapStringToFont(const char *s, int fontCharX, int fontCharY); + parser : now strings can contain octal/hexadecimal ascii values myStringProperty1 = "embedded hex value : \x80" myStringProperty2 = "embedded octal value : \200" + parser : now can handle list properties. myStruct { myProperty = [ 1, 2, 3 ] } to declare : struct.addListProperty("myProperty",TCOD_TYPE_INT,true); to read (default parser) : TCODList prop( parser.getListProperty("myStruct.myProperty",TCOD_TYPE_INT) ); + added color map generator. Interpolate colors from an array of key colors : TCODColor::genMap(TCODColor *map, int nbKey, TCODColor const *keyColor, int const *keyIndex) + added random generator backup function. You can save the state of a generator with TCODRandom *TCODRandom::save() and restore it with void TCODRandom::restore(const TCODRandom *backup) + added simplex noise, similar to perlin but faster, especially in 4 dimensions and has better contrast : TCODNoise::getSimplex TCODNoise::getFbmSimplex TCODNoise::getTurbulenceSimplex Simplex should be preferred over Perlin for most usages. + added wavelet noise, similar to perlin, much slower but doesn't blur at high scales. Doesn't work in 4D : TCODNoise::getWavelet TCODNoise::getFbmWavelet TCODNoise::getTurbulenceWavelet Noise functions relative times : 2D 3D 4D simplex : 1 1 1 perlin : 4 5 17 wavelet : 32 14 X + you can capture a console to an existing image without creating a new image with TCODImage::refreshConsole + non rectangular offscreen consoles : you can define a key color on offscreen consoles. Cells for which background color = key color are not blitted + added libtcod credits function. You can either call : TCODConsole::credits() to print the credits page at the start of your game (just after initRoot) or bool TCODConsole::renderCredits(int x, int y, bool alpha) to print the credits on top of one of your existing page (your game menu for example). Call it until it returns true. % improved TCODConsole::flush performances : frames per second for sample "True colors" (terminal.png font) on my reference computer (windowed mode) : libtcod 1.3.2 : 130 libtcod 1.4.0 : 300 % TCODNoise::getTurbulence is twice faster % improved mouse click detection. Even with a low framerate, mouse clicks will always be detected and reported in the Xbutton_pressed fields of TCOD_mouse_t. % you don't need anymore to provide values in TCODLine::step parameters - fixed memory leak in image module - fixed DELETE and INSERT keys not detected - fixed a rendering bug when using a white background color before any other background color ========================================================= 1.3.2 : 2008 Jul 14 + added documentation for the generic container module TCODList - fixed not being able to open and close the root console more than once - fixed parser not being able to attach a sub-structure to more than one structure - fixed TCOD_image_from_console not working with root console on C version - fixed TCODParser::newStruct, addFlag, addProperty handling only static names - fixed web color parser (#rrggbb) in the parser module - fixed TCODImage constructor / TCOD_image_new crashing if root console not initialized - fixed mouse status not updated if the keyboard events are not read with checkForKeypress/waitForKeypress - fixed fbm, turbulence functions returning NaN for high octaves values ========================================================= 1.3.1 : 2008 Jun 05 + now TCODConsole::putChar/setChar can use ascii code > 255 (ok, it's no more an ascii code, then) this allows you to use fonts with more than 255 characters. + added default parser listener for basic config files. + added fields in TCOD_mouse_t to easily detect button press events : lbutton_pressed : left button pressed event rbutton_pressed : right button pressed event mbutton_pressed : middle button pressed event and to get the mouse movement in cell coordinates (instead of pixels) + added functions to retrieve data from TCODMap - fixed const correctness in TCODConsole::print*Rect functions - fixed a bug in fov toolkit if TCODMap width < height - fixed TCOD_struct_get_type returning TCOD_TYPE_NONE instead of TCOD_TYPE_BOOL for flags. ========================================================= 1.3 : 2008 May 25 X C++ : colors must be initialized by constructor : 1.2.2 : TCODColor mycol={r,g,b}; 1.3 : TCODColor mycol(r,g,b); X TCOD_console_check_for_keypress now has a parameter that indicates which events are tracked 1.2.2 : key = TCOD_console_check_for_keypress(); 1.3 : key = TCOD_console_check_for_keypress(TCOD_KEY_PRESSED); + added mouse support + added the file parser module + added TCODColor::setHSV(float h, float s, float v) and TCODColor::getHSV(float *h, float *s, float *v) + added TCODColor addition and scalar multiplication. All r,g,b values are clamped to [0-255] : C++ : color1 = color2 * 3.5f; color1 = color1 + color2; C : color1 = TCOD_color_multiply_scalar ( color2, 3.5f ); color1 = TCOD_color_add( color1, color2 ); + added TCODConsole::setKeyboardRepeat(int initialDelay, int interval) and TCODConsole::disableKeyboardRepeat() + added TCODSystem::getCurrentResolution(int *w, int *h) % now TCODFov::computeFov takes a maxRadius parameter. Use 0 for unlimited range (default) % the mouse cursor is now automatically hidden when using fullscreen - fixed closing the window resulting in a fake 'Q' keyboard event - fixed TCODConsole::print* and TCODConsole::rect functions crashing when printing out of the console - fixed f parameter modified when calling fbm and turbulence noise functions. Now f is no more modified. - fixed wrong ascii code in TCOD_key_t.c when pressing Control and a letter key. ========================================================= 1.2.2 : 2008 Mar 18 + added helpers for real time games void TCODSystem::setFps(int val) to limit the number of frames per second. Use 0 for unlimited fps (default) int TCODSystem::getFps() to return the number of frames rendered during the last second float TCODSystem::getLastFrameLength() to return the length of the last frame in seconds + added TCODImage::clear to fill an image with a color % TCODConsole::hline and vline now have a TCOD_bkgnd_flag_t parameter % now the TCODConsole::print*Rect functions return the height (number of console lines) of the printed string - fixed TCODConsole::print*Rect functions not truncating the string if it reaches the bottom of the rectangle using a rectangle height of 0 means unlimited height - fixed a color bug when drawing text using the black color (0,0,0) - fixed TCODConsole::waitForKeypress(true) resulting in Alt/Ctrl/Shift key state not cleared ========================================================= 1.2.1 : 2008 Mar 09 + added TCODImage::blitRect to easily map an image on a specific part of a console + added possibility to generate an image from an offscreen console + added TCODImage::save + image toolkit now support reading 8bpp bitmap files. % Random number generators now support inverted ranges instead of crashing : TCODRandom::getInstance()->getInt(10,2) => return a value between 2 and 10. - fixed image toolkit replacing the green component by the red one when loading a bitmap from a file - fixed console print*Rect functions unnecessarily splitting the string in some cases - on Linux, you don't need to link with SDL anymore when using libtcod/libtcod++ - fixed linker issues with Visual Studio ========================================================= 1.2 : 2008 Feb 26 + new 'image' toolkit replacing some of the features previously in the 'system' toolkit. + now windowed mode works even on 16bits desktops + improved custom font support. You can now use fonts with characters ordered in rows or columns and with a custom transparent color. This allows you to use most existing character sets with the doryen library. Font characters with grayscale are still not supported. + new time functions : uint32 TCODSystem::getElapsedMilli() float TCODSystem::getElapsedSeconds() + new background blending modes (see the line sample for a demo) : TCOD_BKGND_LIGHTEN : newbk = MAX(oldbk,curbk) TCOD_BKGND_DARKEN : newbk = MIN(oldbk,curbk) TCOD_BKGND_SCREEN : newbk = white - (white - oldbk) * (white - curbk) // inverse of multiply : (1-newbk) = (1-oldbk)*(1-curbk) TCOD_BKGND_COLOR_DODGE : newbk = curbk / (white - oldbk) TCOD_BKGND_COLOR_BURN : newbk = white - (white - oldbk) / curbk TCOD_BKGND_ADD : newbk = oldbk + curbk TCOD_BKGND_ADDALPHA(alpha) : newbk = oldbk + alpha * curbk, 0.0<=alpha<=1.0 TCOD_BKGND_BURN : newbk = oldbk + curbk - white TCOD_BKGND_OVERLAY : newbk = curbk <= 0.5 ? 2*curbk*oldbk : white - 2*(white-curbk)*(white-oldbk) TCOD_BKGND_ALPHA(alpha) : newbk = (1.0f-alpha)*oldbk + alpha*(curbk-oldbk), 0.0<=alpha<=1.0 + The samples can now use custom bitmap fonts / screen resolution. Use following syntax : sample_c[pp] [options] options : -fullscreen : start directly in fullscreen mode -font (default "terminal.bmp") -font-char-size (default 8 8) -font-layout (default 16 16) -font-in-row : characters in the bitmap are ordered in rows (default : columns) -font-key-color : transparent color, r,g,b between 0 and 255. (default 0 0 0) -fullscreen-resolution (default 640 400) % headers renamed from tcodlib.h* to libtcod.h* % on Linux, the library is split into libtcod.so and libtcod++.so allowing C developpers to use it without installing g++ % the font name is no more a parameter of TCODConsole::initRoot. % TCODConsole::setBitmapFontSize renamed to TCODConsole::setCustomFont % TCODConsole::printFrame is now a variadic function, like the other text output functions % some background blending flags have been renamed : TCOD_BKGND_NOBK replaced by TCOD_BKGND_NONE TCOD_BKGND_BK replaced by TCOD_BKGND_SET % the fov toolkit now uses two properties per cell : transparent/walkable. This is necessary to fix a fov issue with window cells (transparent, but not walkable). void TCODFov::setTransparent(int x,int y, bool isTransparent) has been replaced by : void TCODFov::setProperties(int x,int y, bool isTransparent, bool isWalkable) % improved const correctness, added some default parameter values in the C++ API. - fixed the window size when using a custom font size - fixed TCODK_PRINTSCREEN key event not detected - fixed crash in printing functions if the string length was > 255. Now they can handle strings of any size. ========================================================= 1.1 : 2008 Jan 27 + added the noise toolkit + added the field of view toolkit + added customizable bitmap font size ========================================================= 1.0.1 : 2008 Jan 19 + added C/C++ samples % TCODConsole::waitForKeyPress now has a bool parameter indicating if we flush the keyboard buffer before waiting. - fixed a color bug when drawing text using the grey color (196,196,196) - fixed wrong key codes returned by wait/checkForKeyPress on some keyboard layouts ========================================================= 1.0 : 2008 Jan 05 Initial release libtcod-1.6.4+dfsg/libtcod.cfg000066400000000000000000000013551321276576200162010ustar00rootroot00000000000000/* Use this file to customize the behaviour of libtcod, overriding what's defined in the sample/game code. The main goal of this file is to allow the player to tweak the game in case it doesn't work properly on his system and there are no options screen/config files available in the game. */ libtcod { // uncomment to force the use of a specific renderer // renderer = "GLSL" // renderer = "OPENGL" //renderer = "SDL" // uncomment to force a specific fullscreen resolution /* fullscreen=true fullscreenWidth=1280 fullscreenHeight=1024 */ // uncomment to use a custom font. /* font="data/fonts/terminal8x8_gs_as.png" fontInRow=false fontGreyscale=true fontTcodLayout=false fontNbCharHoriz=16 fontNbCharVertic=16 */ } libtcod-1.6.4+dfsg/lua/000077500000000000000000000000001321276576200146555ustar00rootroot00000000000000libtcod-1.6.4+dfsg/lua/libtcodlua.lua000066400000000000000000000026641321276576200175120ustar00rootroot00000000000000-- load libtcod wrapper if type(loadlib) == "function" then init=loadlib else init=package.loadlib end a,b,c=init("./liblibtcod-lua.so","luaopen_libtcod") if a == nil then a,b,c=init("./liblibtcod-lua.dll","luaopen_libtcod") end a() -- improve the wrapper tcod = { } for key, value in pairs(libtcod) do if type(key) == "string" then local library, name = key:match("^TCOD([^_]*)_(.*)") if library ~= nil then -- replace libtcod.TCODConsole_bla() with tcod.console.bla() library = library:lower( ) tcod[library] = tcod[library] or { } tcod[library][name] = value else library = key:match("^TCOD([^_]*)") if library ~= nil then -- replace libtcod.TCODConsole() with tcod.Console() tcod[library]=value else tcod[key] = value end end else tcod[key] = value end end -- now rename userdata imported from C++ for key,value in pairs(getmetatable(libtcod)[".get"]) do if type(key) == "string" then local library, name = key:match("^TCOD([^_]*)_(.*)") if library ~= nil then -- replace libtcod.TCODColor_grey with tcod.color.grey library = library:lower( ) tcod[library] = tcod[library] or { } tcod[library][name] = value() end end end function _alpha(alpha) return tcod.Alpha + math.floor(alpha*255)*(2^8) end function _addAlpha(alpha) return tcod.AddAlpha + math.floor(alpha*255)*(2^8) end tcod.console.Alpha=_alpha tcod.console.AddAlpha=_addAlpha libtcod-1.6.4+dfsg/lua/samples_lua.lua000066400000000000000000000341121321276576200176660ustar00rootroot00000000000000#!/usr/bin/lua dofile "libtcodlua.lua" SAMPLE_SCREEN_WIDTH = 46 SAMPLE_SCREEN_HEIGHT = 20 SAMPLE_SCREEN_X = 20 SAMPLE_SCREEN_Y = 10 tcod.console.setCustomFont("data/fonts/consolas10x10_gs_tc.png", tcod.Greyscale + tcod.LayoutTCOD) tcod.console.initRoot(80,50,"libtcod lua sample", false, tcod.SDL) root=libtcod.TCODConsole_root sampleConsole = tcod.Console(SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT) first=true rng=tcod.random.getInstance() -- ****************************** -- True colors sample (benchmark) -- ****************************** TOPLEFT = 1 TOPRIGHT = 2 BOTTOMLEFT = 3 BOTTOMRIGHT = 4 -- random starting colors for corners cols={ tcod.Color(50,40,150), tcod.Color(240,85,5), tcod.Color(50,35,240), tcod.Color(10,200,130) } dirr={1,-1,1,1} dirg={1,-1,-1,1} dirb={1,1,1,-1} function render_colors(key) if first then tcod.system.setFps(0) -- unlimited fps sampleConsole:clear() end -- ==== slighty modify the corner colors ==== for c=1,4,1 do -- move each corner color local component=rng:getInt(0,2) if component == 0 then cols[c].Red = cols[c].Red + 5*dirr[c] if cols[c].Red == 255 then dirr[c]=-1 elseif cols[c].Red==0 then dirr[c]=1 end elseif component == 1 then cols[c].Green = cols[c].Green + 5*dirg[c] if cols[c].Green == 255 then dirg[c]=-1 elseif cols[c].Green==0 then dirg[c]=1 end elseif component == 2 then cols[c].Blue = cols[c].Blue + 5*dirb[c] if cols[c].Blue == 255 then dirb[c]=-1 elseif cols[c].Blue==0 then dirb[c]=1 end end end -- ==== scan the whole screen, interpolating corner colors ==== for x=0,SAMPLE_SCREEN_WIDTH-1,1 do local xcoef = x/(SAMPLE_SCREEN_WIDTH-1) -- get the current column top and bottom colors local top = tcod.color.Interpolate(cols[TOPLEFT], cols[TOPRIGHT],xcoef) local bottom = tcod.color.Interpolate(cols[BOTTOMLEFT], cols[BOTTOMRIGHT],xcoef) for y=0,SAMPLE_SCREEN_HEIGHT-1,1 do local ycoef = y/(SAMPLE_SCREEN_HEIGHT-1) -- get the current cell color local curColor = tcod.color.Interpolate(top,bottom,ycoef) sampleConsole:setCharBackground(x,y,curColor,tcod.Set) end end -- ==== print the text with a random color ==== -- get the background color at the text position local textColor=sampleConsole:getCharBackground(SAMPLE_SCREEN_WIDTH/2,5) -- and invert it textColor.Red=255-textColor.Red textColor.Green=255-textColor.Green textColor.Blue=255-textColor.Blue -- put random text (for performance tests) for x=0,SAMPLE_SCREEN_WIDTH-1,1 do for y=0,SAMPLE_SCREEN_HEIGHT-1,1 do local col=sampleConsole:getCharBackground(x,y) col=tcod.color.Interpolate(col,tcod.color.black,0.5) local c=rng:getInt(97,97+25) -- 97 == 'a' sampleConsole:setDefaultForeground(col) sampleConsole:putChar(x,y,c,tcod.None) end end sampleConsole:setDefaultForeground(textColor) -- the background behind the text is slightly darkened using the Multiply flag sampleConsole:setDefaultBackground(tcod.color.grey) sampleConsole:printRectEx(SAMPLE_SCREEN_WIDTH/2,5,SAMPLE_SCREEN_WIDTH-2,SAMPLE_SCREEN_HEIGHT-1, tcod.Multiply,tcod.CenterAlignment, "The Doryen library uses 24 bits colors, for both background and foreground.") end -- *************************** -- offscreen console sample -- *************************** -- a console to store the background screen screenshot = tcod.Console(SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT) -- the offscreen console to blit on top of the background secondary = tcod.Console(SAMPLE_SCREEN_WIDTH/2,SAMPLE_SCREEN_HEIGHT/2) off_init=false off_counter=0 off_x=0 off_y=0 off_xdir=1 off_ydir=1 function render_offscreen(key) if not off_init then -- draw the offscreen console only on first frame off_init=true secondary:printFrame(0,0,SAMPLE_SCREEN_WIDTH/2,SAMPLE_SCREEN_HEIGHT/2,false,tcod.Set,"Offscreen console") secondary:printRectEx(SAMPLE_SCREEN_WIDTH/4,2,SAMPLE_SCREEN_WIDTH/2-2,SAMPLE_SCREEN_HEIGHT/2, tcod.None,tcod.CenterAlignment,"You can render to an offscreen console and blit in on another one, simulating alpha transparency.") end if first then tcod.system.setFps(30) -- fps limited to 30 -- get a "screenshot" of the current sample screen tcod.console.blit(sampleConsole,0,0,SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT, screenshot,0,0); end off_counter = off_counter + 1 if off_counter % 20 == 0 then -- move the secondary screen every 2 seconds off_x = off_x + off_xdir off_y = off_y + off_ydir if off_x >= SAMPLE_SCREEN_WIDTH/2+5 then off_xdir = -1 elseif off_x <= -5 then off_xdir = 1 end if off_y >= SAMPLE_SCREEN_HEIGHT/2+5 then off_ydir = -1 elseif off_y <= -5 then off_ydir = 1 end end -- restore the initial screen tcod.console.blit(screenshot,0,0,SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT, sampleConsole,0,0) -- blit the overlapping screen tcod.console.blit(secondary,0,0,SAMPLE_SCREEN_WIDTH/2,SAMPLE_SCREEN_HEIGHT/2, sampleConsole,off_x,off_y,1.0,0.75) end -- ******************* -- Line drawing sample -- ******************* bk = tcod.Console(SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT) -- colored background bkFlag=tcod.Set line_init=false flagNames={ "None", "Set", "Multiply", "Lighten", "Darken", "Screen", "Dodge", "Burn", "Add", "AddAlpha", "Burn", "Overlay", "Alpha" } function render_lines(key) if key.KeyCode == tcod.Enter or key.KeyCode == tcod.KeypadEnter then -- switch to the next blending mode bkFlag = bkFlag+1 if bkFlag % 256 > tcod.Alpha then bkFlag=tcod.None end end if bkFlag % 256 == tcod.Alpha then -- for the alpha mode, update alpha every frame alpha = (1.0+math.cos(tcod.system.getElapsedSeconds()*2))/2.0 bkFlag=tcod.console.Alpha(alpha) elseif bkFlag % 256 == tcod.AddAlpha then -- for the add alpha mode, update alpha every frame alpha = (1.0+math.cos(tcod.system.getElapsedSeconds()*2))/2.0 bkFlag=tcod.console.AddAlpha(alpha) end if not line_init then -- initialize the colored background for x=0,SAMPLE_SCREEN_WIDTH,1 do for y=0,SAMPLE_SCREEN_HEIGHT,1 do local col = tcod.Color(0,0,0) col.Red = x* 255 / (SAMPLE_SCREEN_WIDTH-1) col.Green = (x+y)* 255 / (SAMPLE_SCREEN_WIDTH-1+SAMPLE_SCREEN_HEIGHT-1) col.Blue = y* 255 / (SAMPLE_SCREEN_HEIGHT-1) bk:setCharBackground(x,y,col) end end line_init=true end if first then tcod.system.setFps(30) -- fps limited to 30 sampleConsole:setDefaultForeground(tcod.color.white) end -- blit the background tcod.console.blit(bk,0,0,SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT,sampleConsole,0,0) -- render the gradient recty=(SAMPLE_SCREEN_HEIGHT-2)*((1.0+math.cos(tcod.system.getElapsedSeconds()))/2.0) for x=0,SAMPLE_SCREEN_WIDTH,1 do local col = tcod.Color(0,0,0) col.Red=x*255/SAMPLE_SCREEN_WIDTH col.Green=x*255/SAMPLE_SCREEN_WIDTH col.Blue=x*255/SAMPLE_SCREEN_WIDTH sampleConsole:setCharBackground(x,recty,col,bkFlag) sampleConsole:setCharBackground(x,recty+1,col,bkFlag) sampleConsole:setCharBackground(x,recty+2,col,bkFlag) end -- calculate the segment ends local angle = tcod.system.getElapsedSeconds()*2.0 local cosAngle=math.cos(angle) local sinAngle=math.sin(angle) local xo = SAMPLE_SCREEN_WIDTH/2*(1 + cosAngle) local yo = SAMPLE_SCREEN_HEIGHT/2 + sinAngle * SAMPLE_SCREEN_WIDTH/2 local xd = SAMPLE_SCREEN_WIDTH/2*(1 - cosAngle) local yd = SAMPLE_SCREEN_HEIGHT/2 - sinAngle * SAMPLE_SCREEN_WIDTH/2 -- render the line tcod.line.init(xo,yo,xd,yd) local x=xo local y=yo repeat if x >= 0 and y >= 0 and x < SAMPLE_SCREEN_WIDTH and y < SAMPLE_SCREEN_HEIGHT then sampleConsole:setCharBackground(x,y,tcod.color.lightBlue,bkFlag) end lineEnd,x,y=tcod.line.step(x,y) until lineEnd -- print the current flag sampleConsole:print(2,2,string.format("%s (ENTER to change)",flagNames[(bkFlag%256)+1])) end -- *************************** -- noise sample -- *************************** -- what noise to render ? PERLIN=0 SIMPLEX=1 WAVELET=2 FBM_PERLIN=3 TURBULENCE_PERLIN=4 FBM_SIMPLEX=5 TURBULENCE_SIMPLEX=6 FBM_WAVELET=7 TURBULENCE_WAVELET=8 funcName={ "1 : perlin noise ", "2 : simplex noise ", "3 : wavelet noise ", "4 : perlin fbm ", "5 : perlin turbulence ", "6 : simplex fbm ", "7 : simplex turbulence ", "8 : wavelet fbm ", "9 : wavelet turbulence " } func=PERLIN noise=nil noise_dx=0 noise_dy=0 octaves=4 hurst=tcod.NoiseDefaultHurst lacunarity=tcod.NoiseDefaultLacunarity noise_img=nil zoom=3 function render_noise(key) if noise == nil then noise = tcod.Noise(2,hurst,lacunarity) img = tcod.Image(SAMPLE_SCREEN_WIDTH*2,SAMPLE_SCREEN_HEIGHT*2) end if first then tcod.system.setFps(30) -- fps limited to 30 end -- texture animation noise_dx = noise_dx+0.01 noise_dy = noise_dy + 0.01 -- render the 2d noise function for y=0,2*SAMPLE_SCREEN_HEIGHT-1,1 do for x=0,2*SAMPLE_SCREEN_WIDTH-1,1 do local f = { zoom*x / (2*SAMPLE_SCREEN_WIDTH) + noise_dx, zoom*y / (2*SAMPLE_SCREEN_HEIGHT) + noise_dy } local value = 0 if func == PERLIN then value = noise:get(f,NoisePerlin) elseif func == SIMPLEX then value = noise:get(f,NoiseSimplex) elseif func == WAVELET then value = noise:get(f,NoiseWavelet) elseif func == FBM_PERLIN then value = noise:getFbm(f,octaves,NOISE_PERLIN) elseif func == TURBULENCE_PERLIN then value = noise:getTurbulence(f,octaves,TCOD_NOISE_PERLIN) elseif func == FBM_SIMPLEX then value = noise:getFbm(f,octaves,NoiseSimplex) elseif func == TURBULENCE_SIMPLEX then value = noise:getTurbulence(f,octaves,NoiseSimplex) elseif func == FBM_WAVELET then value = noise:getFbm(f,octaves,NoiseWavelet) elseif func == TURBULENCE_WAVELET then value = noise:getTurbulence(f,octaves,NoiseWavelet) end local c=math.floor((value+1.0)/2.0*255) -- use a bluish color local col = tcod.Color(c/2,c/2,c) img:putPixel(x,y,col) end end -- blit the noise image on the console with subcell resolution img:blit2x(sampleConsole,0,0); -- draw a transparent rectangle sampleConsole:setBackgroundColor(tcod.color.grey) local ypos=10 if func > WAVELET then ypos = 13 end sampleConsole:rect(2,2,23,ypos,false,tcod.Multiply) for y=2,1+ypos,1 do for x=2,24,1 do local col = sampleConsole:getFore(x,y) col = col * tcod.color.grey sampleConsole:setFore(x,y,col) end end -- draw the text for curfunc=PERLIN,TURBULENCE_WAVELET,1 do if curfunc == func then sampleConsole:setForegroundColor(tcod.color.white) sampleConsole:setBackgroundColor(tcod.color.lightBlue) sampleConsole:printEx(2,2+curfunc,tcod.Set,tcod.LeftAlignment,funcName[curfunc]) else sampleConsole:setForegroundColor(tcod.color.grey) sampleConsole:print(2,2+curfunc,funcName[curfunc]) end end -- draw parameters sampleConsole:setForegroundColor(tcod.color.white) sampleConsole:print(2,11,string.format("Y/H : zoom (%2.1f)",zoom)) if func > WAVELET then sampleConsole:print(2,12,string.format("E/D : hurst (%2.1f)",hurst)) sampleConsole:print(2,13,string.format("R/F : lacunarity (%2.1f)",lacunarity)) sampleConsole:print(2,14,string.format("T/G : octaves (%2.1f)",octaves)) end -- handle keypress if key.KeyCode == tcod.NoKey then return end if key.Character >= '1' and key.Character <= '9' then -- change the noise function func = key.Character - '1' elseif key.Character == 'E' or key.Character == 'e' then -- increase hurst hurst = hurst + 0.1 noise = tcod.Noise(2,hurst,lacunarity) elseif key.Character == 'D' or key.Character == 'd' then -- decrease hurst hurst = hurst - 0.1 noise = tcod.Noise(2,hurst,lacunarity) elseif key.Character == 'R' or key.Character == 'r' then -- increase lacunarity lacunarity = lacunarity + 0.5 noise = tcod.Noise(2,hurst,lacunarity) elseif key.Character == 'F' or key.Character == 'f' then -- decrease lacunarity lacunarity = lacunarity - 0.5 noise = tcod.Noise(2,hurst,lacunarity) elseif key.Character == 'T' or key.Character == 't' then -- increase octaves octaves = octaves + 0.5 elseif key.Character == 'G' or key.Character == 'g' then -- decrease octaves octaves = octaves - 0.5 elseif key.Character == 'Y' or key.Character == 'y' then -- increase zoom zoom = zoom + 0.2 elseif key.Character == 'H' or key.Character == 'h' then -- decrease zoom zoom = zoom - 0.2 end end creditsEnd=false -- list of samples samples = { { name = " True colors ", render = render_colors }, { name = " Offscreen console ", render = render_offscreen }, { name = " Line drawing ", render = render_lines }, { name = " Noise ", render = render_noise } } nbSamples = table.getn(samples) curSample = 1 while not tcod.console.isWindowClosed() do key=tcod.Key() tcod.system.checkForEvent(29,key,nil) -- render current sample samples[curSample].render(key) first=false -- and blit it on the root console tcod.console.blit(sampleConsole, 0, 0, SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT, root, SAMPLE_SCREEN_X, SAMPLE_SCREEN_Y) if not creditsEnd then creditsEnd = tcod.console.renderCredits(60, 43, false) end -- print the list of samples for i=1,nbSamples,1 do if i == curSample then -- set colors for currently selected sample root:setDefaultForeground(tcod.color.white) root:setDefaultBackground(tcod.color.lightBlue) else -- set colors for other samples root:setDefaultForeground(tcod.color.grey) root:setDefaultBackground(tcod.color.black) end -- print the sample name root:printEx(2,46-(nbSamples-i),tcod.Set,tcod.LeftAlignment,samples[i].name) end -- render stats root:setDefaultForeground(tcod.color.grey) root:printEx(79, 46, tcod.None, tcod.RightAlignment, string.format("last frame : %3d ms (%3d fps)" , math.floor(tcod.system.getLastFrameLength() * 1000.0), tcod.system.getFps())) root:printEx(79, 47, tcod.None, tcod.RightAlignment, string.format("elapsed : %8d ms %4.2fs", tcod.system.getElapsedMilli(), tcod.system.getElapsedSeconds())) tcod.console.flush() if key.KeyCode == tcod.Down then -- down arrow : next sample curSample = (curSample+1) if curSample == nbSamples+1 then curSample = 1 end first=true elseif key.KeyCode == tcod.Up then -- up arrow : previous sample curSample = curSample - 1 if curSample == 0 then curSample = nbSamples end first=true elseif key.KeyCode == tcod.PrintScreen then -- save screenshot tcod.system.saveScreenshot("screenshot0.png") end end libtcod-1.6.4+dfsg/python/000077500000000000000000000000001321276576200154155ustar00rootroot00000000000000libtcod-1.6.4+dfsg/python/MANIFEST.in000066400000000000000000000005431321276576200171550ustar00rootroot00000000000000recursive-include data * recursive-include dependencies * recursive-include makefiles * recursive-include include * recursive-include src * recursive-include python *.py include lib/donotremove include *.py include *.cfg include *.in include *.txt include *.png include SDL2.dll exclude python/setup.py exclude python/setup.cfg exclude python/MANIFEST.in libtcod-1.6.4+dfsg/python/libtcodpy/000077500000000000000000000000001321276576200174065ustar00rootroot00000000000000libtcod-1.6.4+dfsg/python/libtcodpy/__init__.py000066400000000000000000003065471321276576200215360ustar00rootroot00000000000000# # libtcod 1.6.4 Python wrapper # Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * The name of Jice or Mingos may not be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # from __future__ import print_function import os import sys import ctypes import struct from ctypes import * # We do not have a fully unicode API on libtcod, so all unicode strings have to # be implicitly converted to ascii, and any unicode specific operations have to # be explicitly made by users # v = v.encode('latin-1') # Returned byte strings from the api, should be converted to unicode, so that # if formatted via %, do not appear as "b'sds'". # v = v.decode("utf-8") is_python_3 = sys.version_info > (3, 0) if is_python_3: def convert_to_ascii(v): if type(v) is str: return v.encode('ascii') return v else: def convert_to_ascii(v): if type(v) is unicode: return v.encode('ascii') return v if not hasattr(ctypes, "c_bool"): # for Python < 2.6 c_bool = c_uint8 c_void = None try: #import NumPy if available import numpy numpy_available = True except ImportError: numpy_available = False LINUX=False MAC=False MINGW=False MSVC=False def _get_cdll(libname): ''' get the library libname using a manual search path that will first check the package directory and then the development path returns the ctypes lib object ''' def get_pe_architecture(filePath): # From: https://github.com/tgandor/meats/blob/master/missing/arch_of.py with open(filePath, 'rb') as f: doshdr = f.read(64) magic, padding, offset = struct.unpack('2s58si', doshdr) # print (magic, offset) if magic != b'MZ': return None f.seek(offset, os.SEEK_SET) pehdr = f.read(6) # careful! H == unsigned short, x64 is negative with signed magic, padding, machine = struct.unpack('2s2sH', pehdr) # print (magic, hex(machine)) if magic != b'PE': return None if machine == 0x014c: return 'i386' if machine == 0x0200: return 'IA64' if machine == 0x8664: return 'x64' return 'unknown' pythonExePath = sys.executable pythonExeArchitecture = get_pe_architecture(pythonExePath) pathsToTry = [] # 1. Try the directory this script is located in. pathsToTry.append(os.path.join(__path__[0], libname)) # 2. Try the directory of the command-line script. scriptFilePath = sys.argv[0] scriptPath = os.path.dirname(scriptFilePath) if len(scriptPath): pathsToTry.append(os.path.join(scriptPath, libname)) else: pathsToTry.append(os.path.join(os.getcwd(), libname)) # 3. Try the environment variable LIBTCOD_DLL_PATH. if "LIBTCOD_DLL_PATH" in os.environ: envPaths = os.environ["LIBTCOD_DLL_PATH"].split(";") for envPath in envPaths: if os.path.exists(envPath): pathsToTry.append(os.path.join(envPath, libname)) # 4. Try the top-level path in the development tree. potentialTopLevelPath = os.path.realpath(os.path.join(__path__[0], os.pardir, os.pardir)) pythonPath = os.path.join(potentialTopLevelPath, "python") if os.path.exists(pythonPath): pathsToTry.append(os.path.join(potentialTopLevelPath, libname)) for libPath in pathsToTry: if os.path.exists(libPath): # get library from the package libArchitecture = get_pe_architecture(libPath) if libArchitecture != pythonExeArchitecture: libName = os.path.basename(libPath) print ("Error: Incompatible architecture, python is %s, %s is %s" % (pythonExeArchitecture, libName, libArchitecture)) sys.exit(1) return ctypes.cdll[libPath] raise Exception("unable to locate: "+ libname) if sys.platform.find('linux') != -1: _lib = _get_cdll('libtcod.so') LINUX=True elif sys.platform.find('darwin') != -1: _lib = _get_cdll('libtcod.dylib') MAC = True elif sys.platform.find('haiku') != -1: _lib = _get_cdll('libtcod.so') HAIKU = True else: _get_cdll('SDL2.dll') _lib = _get_cdll('libtcod.dll') MSVC=True # On Windows, ctypes doesn't work well with function returning structs, # so we have to user the _wrapper functions instead for function_name in [ "TCOD_color_equals", "TCOD_color_add", "TCOD_color_subtract", "TCOD_color_multiply", "TCOD_color_multiply_scalar", "TCOD_color_lerp", "TCOD_color_get_HSV", "TCOD_color_get_hue", "TCOD_color_get_saturation", "TCOD_color_get_value", "TCOD_console_get_default_background", "TCOD_console_get_default_foreground", "TCOD_console_set_default_background", "TCOD_console_set_default_foreground", "TCOD_console_get_char_foreground", "TCOD_console_get_char_background", "TCOD_console_set_char_background", "TCOD_console_set_char_foreground", "TCOD_console_put_char_ex", "TCOD_console_set_fade", "TCOD_console_get_fading_color", "TCOD_console_set_color_control", "TCOD_image_clear", "TCOD_image_get_pixel", "TCOD_image_get_mipmap_pixel", "TCOD_image_put_pixel", "TCOD_image_set_key_color", "TCOD_parser_get_color_property", "TCOD_console_set_key_color", ]: wrapper_func = getattr(_lib, function_name +"_wrapper", None) if wrapper_func is not None: setattr(_lib, function_name, wrapper_func) else: raise Exception("unable to find wrapper", function_name) HEXVERSION = 0x010604 STRVERSION = "1.6.4" TECHVERSION = 0x01060400 ############################ # color module ############################ class Color(Structure): _fields_ = [('r', c_uint8), ('g', c_uint8), ('b', c_uint8), ] def __eq__(self, c): return _lib.TCOD_color_equals(self, c) def __mul__(self, c): if isinstance(c,Color): return _lib.TCOD_color_multiply(self, c) else: return _lib.TCOD_color_multiply_scalar(self, c_float(c)) def __add__(self, c): return _lib.TCOD_color_add(self, c) def __sub__(self, c): return _lib.TCOD_color_subtract(self, c) def __repr__(self): return "Color(%d,%d,%d)" % (self.r, self.g, self.b) def __getitem__(self, i): if type(i) == str: return getattr(self, i) else: return getattr(self, "rgb"[i]) def __setitem__(self, i, c): if type(i) == str: setattr(self, i, c) else: setattr(self, "rgb"[i], c) def __iter__(self): yield self.r yield self.g yield self.b _lib.TCOD_color_equals.restype=c_bool _lib.TCOD_color_equals.argtypes=[Color, Color] _lib.TCOD_color_add.restype=Color _lib.TCOD_color_add.argtypes=[Color, Color] _lib.TCOD_color_subtract.restype=Color _lib.TCOD_color_subtract.argtypes=[Color, Color] _lib.TCOD_color_multiply.restype=Color _lib.TCOD_color_multiply.argtypes=[Color , Color ] _lib.TCOD_color_multiply_scalar.restype=Color _lib.TCOD_color_multiply_scalar.argtypes=[Color , c_float ] # Should be valid on any platform, check it! Has to be done after Color is defined. # NOTE(rmtew): This should ideally be deleted. Most of it is moved or duplicated here. if MAC: from .cprotos import setup_protos setup_protos(_lib) # default colors # grey levels black=Color(0,0,0) darkest_grey=Color(31,31,31) darker_grey=Color(63,63,63) dark_grey=Color(95,95,95) grey=Color(127,127,127) light_grey=Color(159,159,159) lighter_grey=Color(191,191,191) lightest_grey=Color(223,223,223) darkest_gray=Color(31,31,31) darker_gray=Color(63,63,63) dark_gray=Color(95,95,95) gray=Color(127,127,127) light_gray=Color(159,159,159) lighter_gray=Color(191,191,191) lightest_gray=Color(223,223,223) white=Color(255,255,255) # sepia darkest_sepia=Color(31,24,15) darker_sepia=Color(63,50,31) dark_sepia=Color(94,75,47) sepia=Color(127,101,63) light_sepia=Color(158,134,100) lighter_sepia=Color(191,171,143) lightest_sepia=Color(222,211,195) #standard colors red=Color(255,0,0) flame=Color(255,63,0) orange=Color(255,127,0) amber=Color(255,191,0) yellow=Color(255,255,0) lime=Color(191,255,0) chartreuse=Color(127,255,0) green=Color(0,255,0) sea=Color(0,255,127) turquoise=Color(0,255,191) cyan=Color(0,255,255) sky=Color(0,191,255) azure=Color(0,127,255) blue=Color(0,0,255) han=Color(63,0,255) violet=Color(127,0,255) purple=Color(191,0,255) fuchsia=Color(255,0,255) magenta=Color(255,0,191) pink=Color(255,0,127) crimson=Color(255,0,63) # dark colors dark_red=Color(191,0,0) dark_flame=Color(191,47,0) dark_orange=Color(191,95,0) dark_amber=Color(191,143,0) dark_yellow=Color(191,191,0) dark_lime=Color(143,191,0) dark_chartreuse=Color(95,191,0) dark_green=Color(0,191,0) dark_sea=Color(0,191,95) dark_turquoise=Color(0,191,143) dark_cyan=Color(0,191,191) dark_sky=Color(0,143,191) dark_azure=Color(0,95,191) dark_blue=Color(0,0,191) dark_han=Color(47,0,191) dark_violet=Color(95,0,191) dark_purple=Color(143,0,191) dark_fuchsia=Color(191,0,191) dark_magenta=Color(191,0,143) dark_pink=Color(191,0,95) dark_crimson=Color(191,0,47) # darker colors darker_red=Color(127,0,0) darker_flame=Color(127,31,0) darker_orange=Color(127,63,0) darker_amber=Color(127,95,0) darker_yellow=Color(127,127,0) darker_lime=Color(95,127,0) darker_chartreuse=Color(63,127,0) darker_green=Color(0,127,0) darker_sea=Color(0,127,63) darker_turquoise=Color(0,127,95) darker_cyan=Color(0,127,127) darker_sky=Color(0,95,127) darker_azure=Color(0,63,127) darker_blue=Color(0,0,127) darker_han=Color(31,0,127) darker_violet=Color(63,0,127) darker_purple=Color(95,0,127) darker_fuchsia=Color(127,0,127) darker_magenta=Color(127,0,95) darker_pink=Color(127,0,63) darker_crimson=Color(127,0,31) # darkest colors darkest_red=Color(63,0,0) darkest_flame=Color(63,15,0) darkest_orange=Color(63,31,0) darkest_amber=Color(63,47,0) darkest_yellow=Color(63,63,0) darkest_lime=Color(47,63,0) darkest_chartreuse=Color(31,63,0) darkest_green=Color(0,63,0) darkest_sea=Color(0,63,31) darkest_turquoise=Color(0,63,47) darkest_cyan=Color(0,63,63) darkest_sky=Color(0,47,63) darkest_azure=Color(0,31,63) darkest_blue=Color(0,0,63) darkest_han=Color(15,0,63) darkest_violet=Color(31,0,63) darkest_purple=Color(47,0,63) darkest_fuchsia=Color(63,0,63) darkest_magenta=Color(63,0,47) darkest_pink=Color(63,0,31) darkest_crimson=Color(63,0,15) # light colors light_red=Color(255,114,114) light_flame=Color(255,149,114) light_orange=Color(255,184,114) light_amber=Color(255,219,114) light_yellow=Color(255,255,114) light_lime=Color(219,255,114) light_chartreuse=Color(184,255,114) light_green=Color(114,255,114) light_sea=Color(114,255,184) light_turquoise=Color(114,255,219) light_cyan=Color(114,255,255) light_sky=Color(114,219,255) light_azure=Color(114,184,255) light_blue=Color(114,114,255) light_han=Color(149,114,255) light_violet=Color(184,114,255) light_purple=Color(219,114,255) light_fuchsia=Color(255,114,255) light_magenta=Color(255,114,219) light_pink=Color(255,114,184) light_crimson=Color(255,114,149) #lighter colors lighter_red=Color(255,165,165) lighter_flame=Color(255,188,165) lighter_orange=Color(255,210,165) lighter_amber=Color(255,232,165) lighter_yellow=Color(255,255,165) lighter_lime=Color(232,255,165) lighter_chartreuse=Color(210,255,165) lighter_green=Color(165,255,165) lighter_sea=Color(165,255,210) lighter_turquoise=Color(165,255,232) lighter_cyan=Color(165,255,255) lighter_sky=Color(165,232,255) lighter_azure=Color(165,210,255) lighter_blue=Color(165,165,255) lighter_han=Color(188,165,255) lighter_violet=Color(210,165,255) lighter_purple=Color(232,165,255) lighter_fuchsia=Color(255,165,255) lighter_magenta=Color(255,165,232) lighter_pink=Color(255,165,210) lighter_crimson=Color(255,165,188) # lightest colors lightest_red=Color(255,191,191) lightest_flame=Color(255,207,191) lightest_orange=Color(255,223,191) lightest_amber=Color(255,239,191) lightest_yellow=Color(255,255,191) lightest_lime=Color(239,255,191) lightest_chartreuse=Color(223,255,191) lightest_green=Color(191,255,191) lightest_sea=Color(191,255,223) lightest_turquoise=Color(191,255,239) lightest_cyan=Color(191,255,255) lightest_sky=Color(191,239,255) lightest_azure=Color(191,223,255) lightest_blue=Color(191,191,255) lightest_han=Color(207,191,255) lightest_violet=Color(223,191,255) lightest_purple=Color(239,191,255) lightest_fuchsia=Color(255,191,255) lightest_magenta=Color(255,191,239) lightest_pink=Color(255,191,223) lightest_crimson=Color(255,191,207) # desaturated colors desaturated_red=Color(127,63,63) desaturated_flame=Color(127,79,63) desaturated_orange=Color(127,95,63) desaturated_amber=Color(127,111,63) desaturated_yellow=Color(127,127,63) desaturated_lime=Color(111,127,63) desaturated_chartreuse=Color(95,127,63) desaturated_green=Color(63,127,63) desaturated_sea=Color(63,127,95) desaturated_turquoise=Color(63,127,111) desaturated_cyan=Color(63,127,127) desaturated_sky=Color(63,111,127) desaturated_azure=Color(63,95,127) desaturated_blue=Color(63,63,127) desaturated_han=Color(79,63,127) desaturated_violet=Color(95,63,127) desaturated_purple=Color(111,63,127) desaturated_fuchsia=Color(127,63,127) desaturated_magenta=Color(127,63,111) desaturated_pink=Color(127,63,95) desaturated_crimson=Color(127,63,79) # metallic brass=Color(191,151,96) copper=Color(197,136,124) gold=Color(229,191,0) silver=Color(203,203,203) # miscellaneous celadon=Color(172,255,175) peach=Color(255,159,127) # color functions _lib.TCOD_color_lerp.restype = Color def color_lerp(c1, c2, a): return _lib.TCOD_color_lerp(c1, c2, c_float(a)) _lib.TCOD_color_set_HSV.restype=c_void _lib.TCOD_color_set_HSV.argtypes=[POINTER(Color),c_float , c_float , c_float ] def color_set_hsv(c, h, s, v): _lib.TCOD_color_set_HSV(byref(c), c_float(h), c_float(s), c_float(v)) _lib.TCOD_color_get_HSV.restype=c_void _lib.TCOD_color_get_HSV.argtypes=[Color ,POINTER(c_float) , POINTER(c_float) , POINTER(c_float) ] def color_get_hsv(c): h = c_float() s = c_float() v = c_float() _lib.TCOD_color_get_HSV(c, byref(h), byref(s), byref(v)) return h.value, s.value, v.value _lib.TCOD_color_scale_HSV.restype=c_void _lib.TCOD_color_scale_HSV.argtypes=[POINTER(Color), c_float , c_float ] def color_scale_HSV(c, scoef, vcoef) : _lib.TCOD_color_scale_HSV(byref(c),c_float(scoef),c_float(vcoef)) _lib.TCOD_color_gen_map.restype=c_void _lib.TCOD_color_gen_map.argtypes=[POINTER(Color), c_int, POINTER(Color), POINTER(c_int)] def color_gen_map(colors, indexes): ccolors = (Color * len(colors))(*colors) cindexes = (c_int * len(indexes))(*indexes) cres = (Color * (max(indexes) + 1))() _lib.TCOD_color_gen_map(cres, len(colors), ccolors, cindexes) return cres ############################ # console module ############################ class Key(Structure): _fields_=[('vk', c_int), ('c', c_uint8), ('text',c_char * 32), ('pressed', c_bool), ('lalt', c_bool), ('lctrl', c_bool), ('lmeta', c_bool), ('ralt', c_bool), ('rctrl', c_bool), ('rmeta', c_bool), ('shift', c_bool) ] class ConsoleBuffer: # simple console that allows direct (fast) access to cells. simplifies # use of the "fill" functions. def __init__(self, width, height, back_r=0, back_g=0, back_b=0, fore_r=0, fore_g=0, fore_b=0, char=' '): # initialize with given width and height. values to fill the buffer # are optional, defaults to black with no characters. n = width * height self.width = width self.height = height self.clear(back_r, back_g, back_b, fore_r, fore_g, fore_b, char) def clear(self, back_r=0, back_g=0, back_b=0, fore_r=0, fore_g=0, fore_b=0, char=' '): # clears the console. values to fill it with are optional, defaults # to black with no characters. n = self.width * self.height self.back_r = [back_r] * n self.back_g = [back_g] * n self.back_b = [back_b] * n self.fore_r = [fore_r] * n self.fore_g = [fore_g] * n self.fore_b = [fore_b] * n self.char = [ord(char)] * n def copy(self): # returns a copy of this ConsoleBuffer. other = ConsoleBuffer(0, 0) other.width = self.width other.height = self.height other.back_r = list(self.back_r) # make explicit copies of all lists other.back_g = list(self.back_g) other.back_b = list(self.back_b) other.fore_r = list(self.fore_r) other.fore_g = list(self.fore_g) other.fore_b = list(self.fore_b) other.char = list(self.char) return other def set_fore(self, x, y, r, g, b, char): # set the character and foreground color of one cell. i = self.width * y + x self.fore_r[i] = int(r) self.fore_g[i] = int(g) self.fore_b[i] = int(b) self.char[i] = ord(char) def set_back(self, x, y, r, g, b): # set the background color of one cell. i = self.width * y + x self.back_r[i] = int(r) self.back_g[i] = int(g) self.back_b[i] = int(b) def set(self, x, y, back_r, back_g, back_b, fore_r, fore_g, fore_b, char): # set the background color, foreground color and character of one cell. i = self.width * y + x self.back_r[i] = int(back_r) self.back_g[i] = int(back_g) self.back_b[i] = int(back_b) self.fore_r[i] = int(fore_r) self.fore_g[i] = int(fore_g) self.fore_b[i] = int(fore_b) self.char[i] = ord(char) def blit(self, dest, fill_fore=True, fill_back=True): # use libtcod's "fill" functions to write the buffer to a console. if (console_get_width(dest) != self.width or console_get_height(dest) != self.height): raise ValueError('ConsoleBuffer.blit: Destination console has an incorrect size.') s = struct.Struct('%di' % len(self.back_r)) if fill_back: _lib.TCOD_console_fill_background(c_void_p(dest), (c_int * len(self.back_r))(*self.back_r), (c_int * len(self.back_g))(*self.back_g), (c_int * len(self.back_b))(*self.back_b)) if fill_fore: _lib.TCOD_console_fill_foreground(c_void_p(dest), (c_int * len(self.fore_r))(*self.fore_r), (c_int * len(self.fore_g))(*self.fore_g), (c_int * len(self.fore_b))(*self.fore_b)) _lib.TCOD_console_fill_char(c_void_p(dest), (c_int * len(self.char))(*self.char)) _lib.TCOD_console_is_fullscreen.restype = c_bool _lib.TCOD_console_is_window_closed.restype = c_bool _lib.TCOD_console_has_mouse_focus.restype = c_bool _lib.TCOD_console_is_active.restype = c_bool _lib.TCOD_console_get_default_background.restype = Color _lib.TCOD_console_get_default_foreground.restype = Color _lib.TCOD_console_get_char_background.restype = Color _lib.TCOD_console_get_char_foreground.restype = Color _lib.TCOD_console_get_fading_color.restype = Color _lib.TCOD_console_is_key_pressed.restype = c_bool # background rendering modes BKGND_NONE = 0 BKGND_SET = 1 BKGND_MULTIPLY = 2 BKGND_LIGHTEN = 3 BKGND_DARKEN = 4 BKGND_SCREEN = 5 BKGND_COLOR_DODGE = 6 BKGND_COLOR_BURN = 7 BKGND_ADD = 8 BKGND_ADDA = 9 BKGND_BURN = 10 BKGND_OVERLAY = 11 BKGND_ALPH = 12 BKGND_DEFAULT=13 def BKGND_ALPHA(a): return BKGND_ALPH | (int(a * 255) << 8) def BKGND_ADDALPHA(a): return BKGND_ADDA | (int(a * 255) << 8) # non blocking key events types KEY_PRESSED = 1 KEY_RELEASED = 2 # key codes KEY_NONE = 0 KEY_ESCAPE = 1 KEY_BACKSPACE = 2 KEY_TAB = 3 KEY_ENTER = 4 KEY_SHIFT = 5 KEY_CONTROL = 6 KEY_ALT = 7 KEY_PAUSE = 8 KEY_CAPSLOCK = 9 KEY_PAGEUP = 10 KEY_PAGEDOWN = 11 KEY_END = 12 KEY_HOME = 13 KEY_UP = 14 KEY_LEFT = 15 KEY_RIGHT = 16 KEY_DOWN = 17 KEY_PRINTSCREEN = 18 KEY_INSERT = 19 KEY_DELETE = 20 KEY_LWIN = 21 KEY_RWIN = 22 KEY_APPS = 23 KEY_0 = 24 KEY_1 = 25 KEY_2 = 26 KEY_3 = 27 KEY_4 = 28 KEY_5 = 29 KEY_6 = 30 KEY_7 = 31 KEY_8 = 32 KEY_9 = 33 KEY_KP0 = 34 KEY_KP1 = 35 KEY_KP2 = 36 KEY_KP3 = 37 KEY_KP4 = 38 KEY_KP5 = 39 KEY_KP6 = 40 KEY_KP7 = 41 KEY_KP8 = 42 KEY_KP9 = 43 KEY_KPADD = 44 KEY_KPSUB = 45 KEY_KPDIV = 46 KEY_KPMUL = 47 KEY_KPDEC = 48 KEY_KPENTER = 49 KEY_F1 = 50 KEY_F2 = 51 KEY_F3 = 52 KEY_F4 = 53 KEY_F5 = 54 KEY_F6 = 55 KEY_F7 = 56 KEY_F8 = 57 KEY_F9 = 58 KEY_F10 = 59 KEY_F11 = 60 KEY_F12 = 61 KEY_NUMLOCK = 62 KEY_SCROLLLOCK = 63 KEY_SPACE = 64 KEY_CHAR = 65 KEY_TEXT = 66 # special chars # single walls CHAR_HLINE = 196 CHAR_VLINE = 179 CHAR_NE = 191 CHAR_NW = 218 CHAR_SE = 217 CHAR_SW = 192 CHAR_TEEW = 180 CHAR_TEEE = 195 CHAR_TEEN = 193 CHAR_TEES = 194 CHAR_CROSS = 197 # double walls CHAR_DHLINE = 205 CHAR_DVLINE = 186 CHAR_DNE = 187 CHAR_DNW = 201 CHAR_DSE = 188 CHAR_DSW = 200 CHAR_DTEEW = 185 CHAR_DTEEE = 204 CHAR_DTEEN = 202 CHAR_DTEES = 203 CHAR_DCROSS = 206 # blocks CHAR_BLOCK1 = 176 CHAR_BLOCK2 = 177 CHAR_BLOCK3 = 178 # arrows CHAR_ARROW_N = 24 CHAR_ARROW_S = 25 CHAR_ARROW_E = 26 CHAR_ARROW_W = 27 # arrows without tail CHAR_ARROW2_N = 30 CHAR_ARROW2_S = 31 CHAR_ARROW2_E = 16 CHAR_ARROW2_W = 17 # double arrows CHAR_DARROW_H = 29 CHAR_DARROW_V = 18 # GUI stuff CHAR_CHECKBOX_UNSET = 224 CHAR_CHECKBOX_SET = 225 CHAR_RADIO_UNSET = 9 CHAR_RADIO_SET = 10 # sub-pixel resolution kit CHAR_SUBP_NW = 226 CHAR_SUBP_NE = 227 CHAR_SUBP_N = 228 CHAR_SUBP_SE = 229 CHAR_SUBP_DIAG = 230 CHAR_SUBP_E = 231 CHAR_SUBP_SW = 232 # misc characters CHAR_BULLET = 7 CHAR_BULLET_INV = 8 CHAR_BULLET_SQUARE = 254 CHAR_CENT = 189 CHAR_CLUB = 5 CHAR_COPYRIGHT = 184 CHAR_CURRENCY = 207 CHAR_DIAMOND = 4 CHAR_DIVISION = 246 CHAR_EXCLAM_DOUBLE = 19 CHAR_FEMALE = 12 CHAR_FUNCTION = 159 CHAR_GRADE = 248 CHAR_HALF = 171 CHAR_HEART = 3 CHAR_LIGHT = 15 CHAR_MALE = 11 CHAR_MULTIPLICATION = 158 CHAR_NOTE = 13 CHAR_NOTE_DOUBLE = 14 CHAR_ONE_QUARTER = 172 CHAR_PILCROW = 20 CHAR_POUND = 156 CHAR_POW1 = 251 CHAR_POW2 = 253 CHAR_POW3 = 252 CHAR_RESERVED = 169 CHAR_SECTION = 21 CHAR_SMILIE = 1 CHAR_SMILIE_INV = 2 CHAR_SPADE = 6 CHAR_THREE_QUARTERS = 243 CHAR_UMLAUT = 249 CHAR_YEN = 190 # font flags FONT_LAYOUT_ASCII_INCOL = 1 FONT_LAYOUT_ASCII_INROW = 2 FONT_TYPE_GREYSCALE = 4 FONT_TYPE_GRAYSCALE = 4 FONT_LAYOUT_TCOD = 8 # color control codes COLCTRL_1=1 COLCTRL_2=2 COLCTRL_3=3 COLCTRL_4=4 COLCTRL_5=5 COLCTRL_NUMBER=5 COLCTRL_FORE_RGB=6 COLCTRL_BACK_RGB=7 COLCTRL_STOP=8 # renderers RENDERER_GLSL=0 RENDERER_OPENGL=1 RENDERER_SDL=2 NB_RENDERERS=3 # alignment LEFT=0 RIGHT=1 CENTER=2 # initializing the console _lib.TCOD_console_init_root.restype=c_void _lib.TCOD_console_init_root.argtypes=[c_int, c_int, c_char_p , c_bool , c_uint ] def console_init_root(w, h, title, fullscreen=False, renderer=RENDERER_SDL): _lib.TCOD_console_init_root(w, h, convert_to_ascii(title), fullscreen, renderer) _lib.TCOD_console_set_custom_font.restype=c_void _lib.TCOD_console_set_custom_font.argtypes=[c_char_p, c_int,c_int, c_int] def console_set_custom_font(fontFile, flags=FONT_LAYOUT_ASCII_INCOL, nb_char_horiz=0, nb_char_vertic=0): _lib.TCOD_console_set_custom_font(convert_to_ascii(fontFile), flags, nb_char_horiz, nb_char_vertic) _lib.TCOD_console_map_ascii_code_to_font.restype=c_void _lib.TCOD_console_map_ascii_code_to_font.argtypes=[c_int, c_int, c_int] def console_map_ascii_code_to_font(asciiCode, fontCharX, fontCharY): asciiCode = convert_to_ascii(asciiCode) if type(asciiCode) is bytes: _lib.TCOD_console_map_ascii_code_to_font(ord(asciiCode), fontCharX, fontCharY) else: _lib.TCOD_console_map_ascii_code_to_font(asciiCode, fontCharX, fontCharY) _lib.TCOD_console_map_ascii_codes_to_font.restype=c_void _lib.TCOD_console_map_ascii_codes_to_font.argtypes=[c_int, c_int, c_int, c_int] def console_map_ascii_codes_to_font(firstAsciiCode, nbCodes, fontCharX, fontCharY): if type(firstAsciiCode) == str or type(firstAsciiCode) == bytes: _lib.TCOD_console_map_ascii_codes_to_font(ord(firstAsciiCode), nbCodes, fontCharX, fontCharY) else: _lib.TCOD_console_map_ascii_codes_to_font(firstAsciiCode, nbCodes, fontCharX, fontCharY) _lib.TCOD_console_map_string_to_font.argtypes=[c_char_p, c_int, c_int] _lib.TCOD_console_map_string_to_font_utf.argtypes=[c_wchar_p, c_int, c_int] def console_map_string_to_font(s, fontCharX, fontCharY): # Python 3, utf is normal, so if they want utf behaviour call the other function. if type(s) is bytes or is_python_3: _lib.TCOD_console_map_string_to_font(convert_to_ascii(s), fontCharX, fontCharY) else: _lib.TCOD_console_map_string_to_font_utf(s, fontCharX, fontCharY) def console_map_string_to_font_utf(s, fontCharX, fontCharY): _lib.TCOD_console_map_string_to_font_utf(s, fontCharX, fontCharY) _lib.TCOD_console_is_fullscreen.restype=c_bool _lib.TCOD_console_is_fullscreen.argtypes=[] def console_is_fullscreen(): return _lib.TCOD_console_is_fullscreen() _lib.TCOD_console_set_fullscreen.restype=c_void _lib.TCOD_console_set_fullscreen.argtypes=[c_bool ] def console_set_fullscreen(fullscreen): _lib.TCOD_console_set_fullscreen(c_int(fullscreen)) _lib.TCOD_console_is_window_closed.restype=c_bool _lib.TCOD_console_is_window_closed.argtypes=[] def console_is_window_closed(): return _lib.TCOD_console_is_window_closed() _lib.TCOD_console_has_mouse_focus.restype=c_bool _lib.TCOD_console_has_mouse_focus.argtypes=[] def console_has_mouse_focus(): return _lib.TCOD_console_has_mouse_focus() _lib.TCOD_console_is_active.restype=c_bool _lib.TCOD_console_is_active.argtypes=[] def console_is_active(): return _lib.TCOD_console_is_active() _lib.TCOD_console_set_window_title.restype=c_void _lib.TCOD_console_set_window_title.argtypes=[c_char_p] def console_set_window_title(title): _lib.TCOD_console_set_window_title(convert_to_ascii(title)) _lib.TCOD_console_credits_render.restype = c_bool def console_credits(): _lib.TCOD_console_credits() _lib.TCOD_console_credits_reset.restype=c_void _lib.TCOD_console_credits_reset.argtypes=[] def console_credits_reset(): _lib.TCOD_console_credits_reset() _lib.TCOD_console_credits_render.restype=c_bool _lib.TCOD_console_credits_render.argtypes=[c_int, c_int, c_bool ] def console_credits_render(x, y, alpha): return _lib.TCOD_console_credits_render(x, y, c_int(alpha)) _lib.TCOD_console_flush.restype=c_void _lib.TCOD_console_flush.argtypes=[] def console_flush(): _lib.TCOD_console_flush() # drawing on a console _lib.TCOD_console_set_default_background.restype=c_void _lib.TCOD_console_set_default_background.argtypes=[c_void_p ,Color ] def console_set_default_background(con, col): _lib.TCOD_console_set_default_background(con, col) _lib.TCOD_console_set_default_foreground.restype=c_void _lib.TCOD_console_set_default_foreground.argtypes=[c_void_p ,Color ] def console_set_default_foreground(con, col): _lib.TCOD_console_set_default_foreground(con, col) _lib.TCOD_console_clear.restype=c_void _lib.TCOD_console_clear.argtypes=[c_void_p ] def console_clear(con): return _lib.TCOD_console_clear(con) _lib.TCOD_console_put_char.restype=c_void _lib.TCOD_console_put_char.argtypes=[c_void_p ,c_int, c_int, c_int, c_int] def console_put_char(con, x, y, c, flag=BKGND_DEFAULT): if type(c) == str or type(c) == bytes: _lib.TCOD_console_put_char(c_void_p(con), x, y, ord(c), flag) else: _lib.TCOD_console_put_char(c_void_p(con), x, y, c, flag) _lib.TCOD_console_put_char_ex.restype=c_void _lib.TCOD_console_put_char_ex.argtypes=[c_void_p ,c_int, c_int, c_int, Color, Color] def console_put_char_ex(con, x, y, c, fore, back): if type(c) == str or type(c) == bytes: _lib.TCOD_console_put_char_ex(c_void_p(con), x, y, ord(c), fore, back) else: _lib.TCOD_console_put_char_ex(c_void_p(con), x, y, c, fore, back) _lib.TCOD_console_set_char_background.restype=c_void _lib.TCOD_console_set_char_background.argtypes=[c_void_p ,c_int, c_int, Color , c_int ] def console_set_char_background(con, x, y, col, flag=BKGND_SET): _lib.TCOD_console_set_char_background(con, x, y, col, flag) _lib.TCOD_console_set_char_foreground.restype=c_void _lib.TCOD_console_set_char_foreground.argtypes=[c_void_p ,c_int, c_int, Color ] def console_set_char_foreground(con, x, y, col): _lib.TCOD_console_set_char_foreground(con, x, y, col) _lib.TCOD_console_set_char.restype=c_void _lib.TCOD_console_set_char.argtypes=[c_void_p ,c_int, c_int, c_int] def console_set_char(con, x, y, c): if type(c) == str or type(c) == bytes: _lib.TCOD_console_set_char(con, x, y, ord(c)) else: _lib.TCOD_console_set_char(con, x, y, c) _lib.TCOD_console_set_background_flag.restype=c_void _lib.TCOD_console_set_background_flag.argtypes=[c_void_p ,c_int ] def console_set_background_flag(con, flag): _lib.TCOD_console_set_background_flag(con, flag) _lib.TCOD_console_get_background_flag.restype=c_int _lib.TCOD_console_get_background_flag.argtypes=[c_void_p ] def console_get_background_flag(con): return _lib.TCOD_console_get_background_flag(con) _lib.TCOD_console_set_alignment.restype=c_void _lib.TCOD_console_set_alignment.argtypes=[c_void_p ,c_int ] def console_set_alignment(con, alignment): _lib.TCOD_console_set_alignment(con, alignment) _lib.TCOD_console_get_alignment.restype=c_int _lib.TCOD_console_get_alignment.argtypes=[c_void_p ] def console_get_alignment(con): return _lib.TCOD_console_get_alignment(con) _lib.TCOD_console_print.argtypes=[c_void_p,c_int,c_int,c_char_p] def console_print(con, x, y, fmt): if type(fmt) == bytes or is_python_3: _lib.TCOD_console_print(con, x, y, convert_to_ascii(fmt)) else: _lib.TCOD_console_print_utf(con, x, y, fmt) _lib.TCOD_console_print_ex.argtypes=[c_void_p,c_int,c_int,c_int,c_int,c_char_p] _lib.TCOD_console_print_ex_utf.argtypes=[c_void_p, c_int, c_int, c_int, c_int, c_wchar_p] def console_print_ex(con, x, y, flag, alignment, fmt): if type(fmt) == bytes or is_python_3: _lib.TCOD_console_print_ex(con, x, y, flag, alignment, convert_to_ascii(fmt)) else: _lib.TCOD_console_print_ex_utf(con, x, y, flag, alignment, fmt) _lib.TCOD_console_print_rect.argtypes=[c_void_p, c_int, c_int, c_int, c_int, c_char_p] _lib.TCOD_console_print_rect_utf.argtypes=[c_void_p, c_int, c_int, c_int, c_int, c_wchar_p] def console_print_rect(con, x, y, w, h, fmt): if type(fmt) == bytes or is_python_3: return _lib.TCOD_console_print_rect(con, x, y, w, h, convert_to_ascii(fmt)) else: return _lib.TCOD_console_print_rect_utf(con, x, y, w, h, fmt) _lib.TCOD_console_print_rect_ex.argtypes=[c_void_p, c_int, c_int, c_int, c_int, c_int, c_int, c_char_p] _lib.TCOD_console_print_rect_ex_utf.argtypes=[c_void_p, c_int, c_int, c_int, c_int, c_int, c_int, c_wchar_p] def console_print_rect_ex(con, x, y, w, h, flag, alignment, fmt): if type(fmt) == bytes or is_python_3: return _lib.TCOD_console_print_rect_ex(con, x, y, w, h, flag, alignment, convert_to_ascii(fmt)) else: return _lib.TCOD_console_print_rect_ex_utf(con, x, y, w, h, flag, alignment, fmt) _lib.TCOD_console_get_height_rect.argtypes=[c_void_p, c_int, c_int, c_int, c_int, c_char_p] _lib.TCOD_console_get_height_rect_utf.argtypes=[c_void_p, c_int, c_int, c_int, c_int, c_wchar_p] def console_get_height_rect(con, x, y, w, h, fmt): if type(fmt) == bytes or is_python_3: return _lib.TCOD_console_get_height_rect(con, x, y, w, h, convert_to_ascii(fmt)) else: return _lib.TCOD_console_get_height_rect_utf(con, x, y, w, h, fmt) _lib.TCOD_console_rect.argtypes=[ c_void_p, c_int, c_int, c_int, c_int, c_bool, c_int ] def console_rect(con, x, y, w, h, clr, flag=BKGND_DEFAULT): _lib.TCOD_console_rect(con, x, y, w, h, c_int(clr), flag) _lib.TCOD_console_hline.argtypes=[ c_void_p, c_int, c_int, c_int, c_int ] def console_hline(con, x, y, l, flag=BKGND_DEFAULT): _lib.TCOD_console_hline( con, x, y, l, flag) _lib.TCOD_console_vline.argtypes=[ c_void_p, c_int, c_int, c_int, c_int ] def console_vline(con, x, y, l, flag=BKGND_DEFAULT): _lib.TCOD_console_vline( con, x, y, l, flag) _lib.TCOD_console_print_frame.argtypes=[c_void_p,c_int,c_int,c_int,c_int,c_int,c_int,c_char_p] def console_print_frame(con, x, y, w, h, clear=True, flag=BKGND_DEFAULT, fmt=''): _lib.TCOD_console_print_frame(con, x, y, w, h, clear, flag, convert_to_ascii(fmt)) _lib.TCOD_console_get_foreground_color_image.restype=c_void_p _lib.TCOD_console_get_foreground_color_image.argtypes=[c_void_p] def console_get_foreground_image(con): return _lib.TCOD_console_get_foreground_color_image(con) _lib.TCOD_console_get_background_color_image.restype=c_void_p _lib.TCOD_console_get_background_color_image.argtypes=[c_void_p] def console_get_background_image(con): return _lib.TCOD_console_get_background_color_image(con) _lib.TCOD_console_set_color_control.restype=c_void _lib.TCOD_console_set_color_control.argtypes=[c_void_p, Color, Color ] def console_set_color_control(con,fore,back) : _lib.TCOD_console_set_color_control(con,fore,back) _lib.TCOD_console_get_default_background.restype=Color _lib.TCOD_console_get_default_background.argtypes=[c_void_p] def console_get_default_background(con): return _lib.TCOD_console_get_default_background(con) _lib.TCOD_console_get_default_foreground.restype=Color _lib.TCOD_console_get_default_foreground.argtypes=[c_void_p] def console_get_default_foreground(con): return _lib.TCOD_console_get_default_foreground(con) _lib.TCOD_console_get_char_background.restype=Color _lib.TCOD_console_get_char_background.argtypes=[c_void_p, c_int, c_int] def console_get_char_background(con, x, y): return _lib.TCOD_console_get_char_background(con, x, y) _lib.TCOD_console_get_char_foreground.restype=Color _lib.TCOD_console_get_char_foreground.argtypes=[c_void_p, c_int, c_int] def console_get_char_foreground(con, x, y): return _lib.TCOD_console_get_char_foreground(con, x, y) _lib.TCOD_console_get_char.restype=c_int _lib.TCOD_console_get_char.argtypes=[c_void_p, c_int, c_int] def console_get_char(con, x, y): return _lib.TCOD_console_get_char(con, x, y) _lib.TCOD_console_set_fade.restype=c_void _lib.TCOD_console_set_fade.argtypes=[c_byte, Color] def console_set_fade(fade, fadingColor): _lib.TCOD_console_set_fade(fade, fadingColor) _lib.TCOD_console_get_fade.restype=c_byte _lib.TCOD_console_get_fade.argtypes=[] def console_get_fade(): return _lib.TCOD_console_get_fade() _lib.TCOD_console_get_fading_color.restype=Color _lib.TCOD_console_get_fading_color.argtypes=[] def console_get_fading_color(): return _lib.TCOD_console_get_fading_color() # handling keyboard input def console_wait_for_keypress(flush): k=Key() _lib.TCOD_console_wait_for_keypress_wrapper(byref(k),c_bool(flush)) return k def console_check_for_keypress(flags=KEY_RELEASED): k=Key() _lib.TCOD_console_check_for_keypress_wrapper(byref(k),c_int(flags)) return k _lib.TCOD_console_is_key_pressed.restype=c_bool _lib.TCOD_console_is_key_pressed.argtypes=[c_int ] def console_is_key_pressed(key): return _lib.TCOD_console_is_key_pressed(key) # using offscreen consoles _lib.TCOD_console_new.restype=c_void_p _lib.TCOD_console_new.argtypes=[c_int, c_int] def console_new(w, h): return _lib.TCOD_console_new(w, h) _lib.TCOD_console_from_file.restype=c_void_p _lib.TCOD_console_from_file.argtypes=[c_char_p] def console_from_file(filename): return _lib.TCOD_console_from_file(convert_to_ascii(filename)) _lib.TCOD_console_get_width.restype=c_int _lib.TCOD_console_get_width.argtypes=[c_void_p ] def console_get_width(con): return _lib.TCOD_console_get_width(con) _lib.TCOD_console_get_height.restype=c_int _lib.TCOD_console_get_height.argtypes=[c_void_p ] def console_get_height(con): return _lib.TCOD_console_get_height(con) _lib.TCOD_console_blit.argtypes=[c_void_p ,c_int, c_int, c_int, c_int, c_void_p , c_int, c_int, c_float, c_float] def console_blit(src, x, y, w, h, dst, xdst, ydst, ffade=1.0,bfade=1.0): _lib.TCOD_console_blit(src, x, y, w, h, dst, xdst, ydst, c_float(ffade), c_float(bfade)) _lib.TCOD_console_set_key_color.argtypes=[c_void_p ,Color ] def console_set_key_color(con, col): _lib.TCOD_console_set_key_color(c_void_p(con), col) _lib.TCOD_console_set_dirty.restype=c_void _lib.TCOD_console_set_dirty.argtypes=[c_int, c_int, c_int, c_int] def console_set_dirty(x, y, w, h): return _lib.TCOD_console_set_dirty(x, y, w, h) _lib.TCOD_console_delete.argtypes=[c_void_p ] def console_delete(con): _lib.TCOD_console_delete(con) # fast color filling _lib.TCOD_console_fill_foreground.restype=c_void _lib.TCOD_console_fill_foreground.argtypes=[c_void_p , POINTER(c_int), POINTER(c_int), POINTER(c_int)] def console_fill_foreground(con,r,g,b) : if len(r) != len(g) or len(r) != len(b): raise TypeError('R, G and B must all have the same size.') if (numpy_available and isinstance(r, numpy.ndarray) and isinstance(g, numpy.ndarray) and isinstance(b, numpy.ndarray)): #numpy arrays, use numpy's ctypes functions r = numpy.ascontiguousarray(r, dtype=numpy.int32) g = numpy.ascontiguousarray(g, dtype=numpy.int32) b = numpy.ascontiguousarray(b, dtype=numpy.int32) cr = r.ctypes.data_as(POINTER(c_int)) cg = g.ctypes.data_as(POINTER(c_int)) cb = b.ctypes.data_as(POINTER(c_int)) else: # otherwise convert using ctypes arrays cr = (c_int * len(r))(*r) cg = (c_int * len(g))(*g) cb = (c_int * len(b))(*b) _lib.TCOD_console_fill_foreground(c_void_p(con), cr, cg, cb) _lib.TCOD_console_fill_background.restype=c_void _lib.TCOD_console_fill_background.argtypes=[c_void_p , POINTER(c_int), POINTER(c_int), POINTER(c_int)] def console_fill_background(con,r,g,b) : if len(r) != len(g) or len(r) != len(b): raise TypeError('R, G and B must all have the same size.') if (numpy_available and isinstance(r, numpy.ndarray) and isinstance(g, numpy.ndarray) and isinstance(b, numpy.ndarray)): #numpy arrays, use numpy's ctypes functions r = numpy.ascontiguousarray(r, dtype=numpy.int32) g = numpy.ascontiguousarray(g, dtype=numpy.int32) b = numpy.ascontiguousarray(b, dtype=numpy.int32) cr = r.ctypes.data_as(POINTER(c_int)) cg = g.ctypes.data_as(POINTER(c_int)) cb = b.ctypes.data_as(POINTER(c_int)) else: # otherwise convert using ctypes arrays cr = (c_int * len(r))(*r) cg = (c_int * len(g))(*g) cb = (c_int * len(b))(*b) _lib.TCOD_console_fill_background(c_void_p(con), cr, cg, cb) _lib.TCOD_console_fill_char.restype=c_void _lib.TCOD_console_fill_char.argtypes=[c_void_p , POINTER(c_int)] def console_fill_char(con,arr) : if (numpy_available and isinstance(arr, numpy.ndarray) ): #numpy arrays, use numpy's ctypes functions arr = numpy.ascontiguousarray(arr, dtype=numpy.int32) carr = arr.ctypes.data_as(POINTER(c_int)) else: carr = (c_int * len(arr))(*arr) _lib.TCOD_console_fill_char(c_void_p(con), carr) _lib.TCOD_console_load_asc.restype=c_bool _lib.TCOD_console_load_asc.argtypes=[c_void_p , c_char_p] def console_load_asc(con, filename) : return _lib.TCOD_console_load_asc(con,convert_to_ascii(filename)) _lib.TCOD_console_save_asc.restype=c_bool _lib.TCOD_console_save_asc.argtypes=[c_void_p , c_char_p] def console_save_asc(con, filename) : return _lib.TCOD_console_save_asc(con,convert_to_ascii(filename)) _lib.TCOD_console_load_apf.restype=c_bool _lib.TCOD_console_load_apf.argtypes=[c_void_p , c_char_p] def console_load_apf(con, filename) : return _lib.TCOD_console_load_apf(con,convert_to_ascii(filename)) _lib.TCOD_console_save_apf.restype=c_bool _lib.TCOD_console_save_apf.argtypes=[c_void_p , c_char_p] def console_save_apf(con, filename) : return _lib.TCOD_console_save_apf(con,convert_to_ascii(filename)) _lib.TCOD_console_from_xp.restype = c_void_p _lib.TCOD_console_from_xp.argtypes = [c_char_p] def console_from_xp(filename): return _lib.TCOD_console_from_xp(filename.encode('utf-8')) _lib.TCOD_console_load_xp.restype = c_bool _lib.TCOD_console_load_xp.argtypes = [c_void_p, c_char_p] def console_load_xp(con, filename): return _lib.TCOD_console_load_xp(con, filename.encode('utf-8')) _lib.TCOD_console_save_xp.restype = c_bool _lib.TCOD_console_save_xp.argtypes = [c_void_p, c_char_p, c_int] def console_save_xp(con, filename, compress_level=9): return _lib.TCOD_console_save_xp(con, filename.encode('utf-8'), compress_level) _lib.TCOD_console_list_from_xp.restype = c_void_p _lib.TCOD_console_list_from_xp.argtypes = [c_char_p] def console_list_load_xp(filename): tcod_list = _lib.TCOD_console_list_from_xp(filename.encode('utf-8')) if not tcod_list: return None try: python_list = [] _lib.TCOD_list_reverse(tcod_list) while not _lib.TCOD_list_is_empty(tcod_list): python_list.append(_lib.TCOD_list_pop(tcod_list)) return python_list finally: _lib.TCOD_list_delete(tcod_list) _lib.TCOD_console_list_save_xp.restype = c_bool _lib.TCOD_console_list_save_xp.argtypes = [c_void_p, c_char_p, c_int] def console_list_save_xp(console_list, filename, compress_level=9): tcod_list = _lib.TCOD_list_new() try: for console in console_list: _lib.TCOD_list_push(tcod_list, console) return _lib.TCOD_console_list_save_xp( tcod_list, filename.encode('utf-8'), compress_level ) finally: _lib.TCOD_list_delete(tcod_list) ############################ # sys module ############################ _lib.TCOD_sys_startup.restype=c_void _lib.TCOD_sys_startup.argtypes=[] def sys_startup(): _lib.TCOD_sys_startup() _lib.TCOD_sys_shutdown.restype=c_void _lib.TCOD_sys_shutdown.argtypes=[] def sys_shutdown(): _lib.TCOD_sys_shutdown() _lib.TCOD_sys_get_last_frame_length.restype = c_float _lib.TCOD_sys_elapsed_seconds.restype = c_float # high precision time functions _lib.TCOD_sys_set_fps.restype=c_void _lib.TCOD_sys_set_fps.argtypes=[c_int] def sys_set_fps(fps): _lib.TCOD_sys_set_fps(fps) _lib.TCOD_sys_get_fps.restype=c_int _lib.TCOD_sys_get_fps.argtypes=[] def sys_get_fps(): return _lib.TCOD_sys_get_fps() _lib.TCOD_sys_get_last_frame_length.restype=c_float _lib.TCOD_sys_get_last_frame_length.argtypes=[] def sys_get_last_frame_length(): return _lib.TCOD_sys_get_last_frame_length() _lib.TCOD_sys_sleep_milli.restype=c_void _lib.TCOD_sys_sleep_milli.argtypes=[c_uint ] def sys_sleep_milli(val): _lib.TCOD_sys_sleep_milli(val) _lib.TCOD_sys_elapsed_milli.restype=c_int _lib.TCOD_sys_elapsed_milli.argtypes=[] def sys_elapsed_milli(): return _lib.TCOD_sys_elapsed_milli() _lib.TCOD_sys_elapsed_seconds.restype=c_float _lib.TCOD_sys_elapsed_seconds.argtypes=[] def sys_elapsed_seconds(): return _lib.TCOD_sys_elapsed_seconds() _lib.TCOD_sys_set_renderer.restype=c_void _lib.TCOD_sys_set_renderer.argtypes=[c_int ] def sys_set_renderer(renderer): _lib.TCOD_sys_set_renderer(renderer) _lib.TCOD_sys_get_renderer.restype=c_int _lib.TCOD_sys_get_renderer.argtypes=[] def sys_get_renderer(): return _lib.TCOD_sys_get_renderer() # easy screenshots _lib.TCOD_sys_save_screenshot.restype=c_void _lib.TCOD_sys_save_screenshot.argtypes=[c_char_p] def sys_save_screenshot(name=0): _lib.TCOD_sys_save_screenshot(convert_to_ascii(name)) # clipboard support # This maps to the SDL2 API, so only uses utf-8 for both Python 2 and 3. _lib.TCOD_sys_clipboard_set.restype=c_bool _lib.TCOD_sys_clipboard_set.argtypes=[c_char_p] def sys_clipboard_set(text): return _lib.TCOD_sys_clipboard_set(text.encode("utf-8")) _lib.TCOD_sys_clipboard_get.restype=c_char_p _lib.TCOD_sys_clipboard_get.argtypes=[] def sys_clipboard_get(): return _lib.TCOD_sys_clipboard_get().decode("utf-8") # custom fullscreen resolution _lib.TCOD_sys_force_fullscreen_resolution.restype=c_void _lib.TCOD_sys_force_fullscreen_resolution.argtypes=[c_int, c_int] def sys_force_fullscreen_resolution(width, height): _lib.TCOD_sys_force_fullscreen_resolution(width, height) _lib.TCOD_sys_get_current_resolution.restype=c_void _lib.TCOD_sys_get_current_resolution.argtypes=[POINTER(c_int), POINTER(c_int)] def sys_get_current_resolution(): w = c_int() h = c_int() _lib.TCOD_sys_get_current_resolution(byref(w), byref(h)) return w.value, h.value _lib.TCOD_sys_get_fullscreen_offsets.restype=c_void _lib.TCOD_sys_get_fullscreen_offsets.argtypes=[POINTER(c_int), POINTER(c_int)] _lib.TCOD_sys_get_char_size.restype=c_void _lib.TCOD_sys_get_char_size.argtypes=[POINTER(c_int), POINTER(c_int)] def sys_get_char_size(): w = c_int() h = c_int() _lib.TCOD_sys_get_char_size(byref(w), byref(h)) return w.value, h.value # update font bitmap _lib.TCOD_sys_update_char.restype=c_void _lib.TCOD_sys_update_char.argtypes=[c_int, c_int, c_int, c_void_p , c_int, c_int] def sys_update_char(asciiCode, fontx, fonty, img, x, y) : _lib.TCOD_sys_update_char(asciiCode,fontx,fonty,img,x,y) # custom SDL post renderer SDL_RENDERER_FUNC = CFUNCTYPE(None, c_void_p) def sys_register_SDL_renderer(callback): global sdl_renderer_func sdl_renderer_func = SDL_RENDERER_FUNC(callback) _lib.TCOD_sys_register_SDL_renderer(sdl_renderer_func) # events EVENT_NONE=0 EVENT_KEY_PRESS=1 EVENT_KEY_RELEASE=2 EVENT_KEY=EVENT_KEY_PRESS|EVENT_KEY_RELEASE EVENT_MOUSE_MOVE=4 EVENT_MOUSE_PRESS=8 EVENT_MOUSE_RELEASE=16 EVENT_MOUSE=EVENT_MOUSE_MOVE|EVENT_MOUSE_PRESS|EVENT_MOUSE_RELEASE EVENT_ANY=EVENT_KEY|EVENT_MOUSE _lib.TCOD_sys_check_for_event.restype=c_int _lib.TCOD_sys_check_for_event.argtypes=[c_int, c_void_p, c_void_p] def sys_check_for_event(mask,k,m) : return _lib.TCOD_sys_check_for_event(mask,byref(k),byref(m)) _lib.TCOD_sys_wait_for_event.restype=c_int _lib.TCOD_sys_wait_for_event.argtypes=[c_int, c_void_p, c_void_p, c_bool ] def sys_wait_for_event(mask,k,m,flush) : return _lib.TCOD_sys_wait_for_event(mask,byref(k),byref(m),flush) ############################ # line module ############################ def line_init(xo, yo, xd, yd): _lib.TCOD_line_init(xo, yo, xd, yd) _lib.TCOD_line_step.restype = c_bool _lib.TCOD_line_step.argtypes=[POINTER(c_int), POINTER(c_int)] def line_step(): x = c_int() y = c_int() ret = _lib.TCOD_line_step(byref(x), byref(y)) if not ret: return x.value, y.value return None,None _lib.TCOD_line.restype=c_bool def line(xo,yo,xd,yd,py_callback) : LINE_CBK_FUNC=CFUNCTYPE(c_bool,c_int,c_int) c_callback=LINE_CBK_FUNC(py_callback) return _lib.TCOD_line(xo,yo,xd,yd,c_callback) _lib.TCOD_line_init_mt.restype=c_void _lib.TCOD_line_init_mt.argtypes=[c_int, c_int, c_int, c_int, c_void_p] _lib.TCOD_line_step_mt.restype = c_bool _lib.TCOD_line_step_mt.argtypes=[POINTER(c_int), POINTER(c_int), c_void_p] def line_iter(xo, yo, xd, yd): data = (c_int * 9)() # struct TCOD_bresenham_data_t _lib.TCOD_line_init_mt(xo, yo, xd, yd, data) x = c_int(xo) y = c_int(yo) done = False while not done: yield x.value, y.value done = _lib.TCOD_line_step_mt(byref(x), byref(y), data) ############################ # image module ############################ _lib.TCOD_image_new.restype=c_void_p _lib.TCOD_image_new.argtypes=[c_int, c_int] def image_new(width, height): return _lib.TCOD_image_new(width, height) _lib.TCOD_image_clear.restype=c_void _lib.TCOD_image_clear.argtypes=[c_void_p , Color ] def image_clear(image,col) : _lib.TCOD_image_clear(image,col) _lib.TCOD_image_invert.restype=c_void _lib.TCOD_image_invert.argtypes=[c_void_p ] def image_invert(image) : _lib.TCOD_image_invert(image) _lib.TCOD_image_hflip.restype=c_void _lib.TCOD_image_hflip.argtypes=[c_void_p ] def image_hflip(image) : _lib.TCOD_image_hflip(image) _lib.TCOD_image_rotate90.restype=c_void _lib.TCOD_image_rotate90.argtypes=[c_void_p , c_int] def image_rotate90(image, num=1) : _lib.TCOD_image_rotate90(image,num) _lib.TCOD_image_vflip.restype=c_void _lib.TCOD_image_vflip.argtypes=[c_void_p ] def image_vflip(image) : _lib.TCOD_image_vflip(image) _lib.TCOD_image_scale.restype=c_void _lib.TCOD_image_scale.argtypes=[c_void_p , c_int, c_int] def image_scale(image, neww, newh) : _lib.TCOD_image_scale(image,neww,newh) _lib.TCOD_image_set_key_color.restype=c_void _lib.TCOD_image_set_key_color.argtypes=[c_void_p , Color] def image_set_key_color(image,col) : _lib.TCOD_image_set_key_color(image,col) _lib.TCOD_image_get_alpha.restype=c_int _lib.TCOD_image_get_alpha.argtypes=[c_void_p ,c_int, c_int] def image_get_alpha(image,x,y) : return _lib.TCOD_image_get_alpha(image,c_int(x),c_int(y)) _lib.TCOD_image_is_pixel_transparent.restype = c_bool _lib.TCOD_image_is_pixel_transparent.argtypes=[c_void_p , c_int, c_int] def image_is_pixel_transparent(image,x,y) : return _lib.TCOD_image_is_pixel_transparent(image,c_int(x),c_int(y)) _lib.TCOD_image_load.restype=c_void_p _lib.TCOD_image_load.argtypes=[c_char_p] def image_load(filename): return _lib.TCOD_image_load(convert_to_ascii(filename)) _lib.TCOD_image_from_console.restype=c_void_p _lib.TCOD_image_from_console.argtypes=[c_void_p ] def image_from_console(console): return _lib.TCOD_image_from_console(console) _lib.TCOD_image_refresh_console.restype=c_void _lib.TCOD_image_refresh_console.argtypes=[c_void_p , c_void_p ] def image_refresh_console(image, console): _lib.TCOD_image_refresh_console(image, console) _lib.TCOD_image_get_size.restype=c_void _lib.TCOD_image_get_size.argtypes=[c_void_p , POINTER(c_int),POINTER(c_int)] def image_get_size(image): w=c_int() h=c_int() _lib.TCOD_image_get_size(image, byref(w), byref(h)) return w.value, h.value _lib.TCOD_image_get_pixel.restype = Color _lib.TCOD_image_get_pixel.argtypes=[c_void_p ,c_int, c_int] def image_get_pixel(image, x, y): return _lib.TCOD_image_get_pixel(image, x, y) _lib.TCOD_image_get_mipmap_pixel.restype = Color _lib.TCOD_image_get_mipmap_pixel.argtypes=[c_void_p ,c_float,c_float, c_float, c_float] def image_get_mipmap_pixel(image, x0, y0, x1, y1): return _lib.TCOD_image_get_mipmap_pixel(image, c_float(x0), c_float(y0), c_float(x1), c_float(y1)) _lib.TCOD_image_put_pixel.restype=c_void _lib.TCOD_image_put_pixel.argtypes=[ c_void_p ,c_int, c_int, Color ] def image_put_pixel(image, x, y, col): _lib.TCOD_image_put_pixel(image, x, y, col) _lib.TCOD_image_blit.restype=c_void _lib.TCOD_image_blit.argtypes=[c_void_p, c_void_p, c_float, c_float, c_int, c_float, c_float, c_float] def image_blit(image, console, x, y, bkgnd_flag, scalex, scaley, angle): _lib.TCOD_image_blit(image, console, x, y, bkgnd_flag, scalex, scaley, angle) _lib.TCOD_image_blit_rect.restype=c_void _lib.TCOD_image_blit_rect.argtypes=[c_void_p , c_void_p , c_int, c_int, c_int, c_int,] def image_blit_rect(image, console, x, y, w, h, bkgnd_flag): _lib.TCOD_image_blit_rect(image, console, x, y, w, h, bkgnd_flag) _lib.TCOD_image_blit_2x.restype=c_void _lib.TCOD_image_blit_2x.argtypes=[c_void_p , c_void_p , c_int, c_int, c_int, c_int, c_int, c_int] def image_blit_2x(image, console, dx, dy, sx=0, sy=0, w=-1, h=-1): _lib.TCOD_image_blit_2x(image, console, dx,dy,sx,sy,w,h) _lib.TCOD_image_save.restype=c_void _lib.TCOD_image_save.argtypes=[c_void_p, c_char_p] def image_save(image, filename): _lib.TCOD_image_save(image, convert_to_ascii(filename)) _lib.TCOD_image_delete.restype=c_void _lib.TCOD_image_delete.argtypes=[c_void_p] def image_delete(image): _lib.TCOD_image_delete(image) ############################ # mouse module ############################ class Mouse(Structure): _fields_=[('x', c_int), ('y', c_int), ('dx', c_int), ('dy', c_int), ('cx', c_int), ('cy', c_int), ('dcx', c_int), ('dcy', c_int), ('lbutton', c_bool), ('rbutton', c_bool), ('mbutton', c_bool), ('lbutton_pressed', c_bool), ('rbutton_pressed', c_bool), ('mbutton_pressed', c_bool), ('wheel_up', c_bool), ('wheel_down', c_bool), ] _lib.TCOD_mouse_is_cursor_visible.restype = c_bool _lib.TCOD_mouse_show_cursor.restype=c_void _lib.TCOD_mouse_show_cursor.argtypes=[c_bool ] def mouse_show_cursor(visible): _lib.TCOD_mouse_show_cursor(c_int(visible)) _lib.TCOD_mouse_is_cursor_visible.restype=c_bool _lib.TCOD_mouse_is_cursor_visible.argtypes=[] def mouse_is_cursor_visible(): return _lib.TCOD_mouse_is_cursor_visible() _lib.TCOD_mouse_move.restype=c_void _lib.TCOD_mouse_move.argtypes=[c_int, c_int] def mouse_move(x, y): _lib.TCOD_mouse_move(x, y) _lib.TCOD_mouse_get_status_wrapper.restype=c_void _lib.TCOD_mouse_get_status_wrapper.argtypes=[c_void_p] def mouse_get_status(): mouse=Mouse() _lib.TCOD_mouse_get_status_wrapper(byref(mouse)) return mouse ############################ # parser module ############################ class Dice(Structure): _fields_=[('nb_dices', c_int), ('nb_faces', c_int), ('multiplier', c_float), ('addsub', c_float), ] def __repr__(self): return "Dice(%d, %d, %s, %s)" % (self.nb_dices, self.nb_faces, self.multiplier, self.addsub) class _CValue(Union): _fields_=[('c',c_uint8), ('i',c_int), ('f',c_float), ('s',c_char_p), # JBR03192012 See http://bugs.python.org/issue14354 for why these are not defined as their actual types ('col',c_uint8 * 3), ('dice',c_int * 4), ('custom',c_void_p), ] _CFUNC_NEW_STRUCT = CFUNCTYPE(c_uint, c_void_p, c_char_p) _CFUNC_NEW_FLAG = CFUNCTYPE(c_uint, c_char_p) _CFUNC_NEW_PROPERTY = CFUNCTYPE(c_uint, c_char_p, c_int, _CValue) class _CParserListener(Structure): _fields_=[('new_struct', _CFUNC_NEW_STRUCT), ('new_flag',_CFUNC_NEW_FLAG), ('new_property',_CFUNC_NEW_PROPERTY), ('end_struct',_CFUNC_NEW_STRUCT), ('error',_CFUNC_NEW_FLAG), ] # property types TYPE_NONE = 0 TYPE_BOOL = 1 TYPE_CHAR = 2 TYPE_INT = 3 TYPE_FLOAT = 4 TYPE_STRING = 5 TYPE_COLOR = 6 TYPE_DICE = 7 TYPE_VALUELIST00 = 8 TYPE_VALUELIST01 = 9 TYPE_VALUELIST02 = 10 TYPE_VALUELIST03 = 11 TYPE_VALUELIST04 = 12 TYPE_VALUELIST05 = 13 TYPE_VALUELIST06 = 14 TYPE_VALUELIST07 = 15 TYPE_VALUELIST08 = 16 TYPE_VALUELIST09 = 17 TYPE_VALUELIST10 = 18 TYPE_VALUELIST11 = 19 TYPE_VALUELIST12 = 20 TYPE_VALUELIST13 = 21 TYPE_VALUELIST14 = 22 TYPE_VALUELIST15 = 23 TYPE_LIST = 1024 _lib.TCOD_list_get.restype = c_void_p def _convert_TCODList(clist, typ): res = list() for i in range(_lib.TCOD_list_size(c_void_p(clist))): elt = _lib.TCOD_list_get(c_void_p(clist), i) elt = cast(elt, c_void_p) if typ == TYPE_BOOL: elt = c_bool.from_buffer(elt).value elif typ == TYPE_CHAR: elt = c_char.from_buffer(elt).value elif typ == TYPE_INT: elt = c_int.from_buffer(elt).value elif typ == TYPE_FLOAT: elt = c_float.from_buffer(elt).value elif typ == TYPE_STRING or TYPE_VALUELIST15 >= typ >= TYPE_VALUELIST00: elt = cast(elt, c_char_p).value elif typ == TYPE_COLOR: elt = Color.from_buffer_copy(elt) elif typ == TYPE_DICE: # doesn't work elt = Dice.from_buffer_copy(elt) res.append(elt) return res _lib.TCOD_parser_new.restype=c_void_p _lib.TCOD_parser_new.argtypes=[] def parser_new(): return _lib.TCOD_parser_new() _lib.TCOD_parser_new_struct.restype=c_void_p _lib.TCOD_parser_new_struct.argtypes=[c_void_p , c_char_p] def parser_new_struct(parser, name): return _lib.TCOD_parser_new_struct(parser, convert_to_ascii(name)) _lib.TCOD_struct_add_flag.restype=c_void _lib.TCOD_struct_add_flag.argtypes=[c_void_p ,c_char_p] def struct_add_flag(struct, name): _lib.TCOD_struct_add_flag(struct, convert_to_ascii(name)) _lib.TCOD_struct_add_property.restype=c_void _lib.TCOD_struct_add_property.argtypes=[c_void_p , c_char_p,c_int , c_bool ] def struct_add_property(struct, name, typ, mandatory): _lib.TCOD_struct_add_property(struct, convert_to_ascii(name), typ, mandatory) _lib.TCOD_struct_add_value_list.restype=c_void _lib.TCOD_struct_add_value_list.argtypes=[c_void_p ,c_char_p, POINTER(c_char_p), c_bool ] def struct_add_value_list(struct, name, value_list, mandatory): CARRAY = c_char_p * (len(value_list) + 1) cvalue_list = CARRAY() for i in range(len(value_list)): cvalue_list[i] = cast(convert_to_ascii(value_list[i]), c_char_p) cvalue_list[len(value_list)] = 0 _lib.TCOD_struct_add_value_list(struct, convert_to_ascii(name), cvalue_list, mandatory) _lib.TCOD_struct_add_value_list_sized.restype=c_void _lib.TCOD_struct_add_value_list_sized.argtypes=[c_void_p ,c_char_p, POINTER(c_char_p), c_int, c_bool ] _lib.TCOD_struct_add_list_property.restype=c_void _lib.TCOD_struct_add_list_property.argtypes=[c_void_p , c_char_p,c_int , c_bool ] def struct_add_list_property(struct, name, typ, mandatory): _lib.TCOD_struct_add_list_property(struct, convert_to_ascii(name), typ, mandatory) _lib.TCOD_struct_add_structure.restype=c_void _lib.TCOD_struct_add_structure.argtypes=[c_void_p ,c_void_p] def struct_add_structure(struct, sub_struct): _lib.TCOD_struct_add_structure(struct, sub_struct) _lib.TCOD_struct_get_name.restype=c_char_p _lib.TCOD_struct_get_name.argtypes=[c_void_p ] def struct_get_name(struct): ret = _lib.TCOD_struct_get_name(struct) if is_python_3: return ret.decode("utf-8") return ret _lib.TCOD_struct_is_mandatory.restype=c_bool _lib.TCOD_struct_is_mandatory.argtypes=[c_void_p ,c_char_p] def struct_is_mandatory(struct, name): return _lib.TCOD_struct_is_mandatory(struct, convert_to_ascii(name)) _lib.TCOD_struct_get_type.restype=c_int _lib.TCOD_struct_get_type.argtypes=[c_void_p , c_char_p] def struct_get_type(struct, name): return _lib.TCOD_struct_get_type(struct, convert_to_ascii(name)) _lib.TCOD_parser_run.restype=c_void _lib.TCOD_parser_run.argtypes=[c_void_p , c_char_p, c_void_p] def parser_run(parser, filename, listener=0): if listener != 0: clistener=_CParserListener() def value_converter(name, typ, value): if typ == TYPE_BOOL: return listener.new_property(name, typ, value.c == 1) elif typ == TYPE_CHAR: return listener.new_property(name, typ, '%c' % (value.c & 0xFF)) elif typ == TYPE_INT: return listener.new_property(name, typ, value.i) elif typ == TYPE_FLOAT: return listener.new_property(name, typ, value.f) elif typ == TYPE_STRING or \ TYPE_VALUELIST15 >= typ >= TYPE_VALUELIST00: return listener.new_property(name, typ, value.s) elif typ == TYPE_COLOR: col = cast(value.col, POINTER(Color)).contents return listener.new_property(name, typ, col) elif typ == TYPE_DICE: dice = cast(value.dice, POINTER(Dice)).contents return listener.new_property(name, typ, dice) elif typ & TYPE_LIST: return listener.new_property(name, typ, _convert_TCODList(value.custom, typ & 0xFF)) return True clistener.new_struct = _CFUNC_NEW_STRUCT(listener.new_struct) clistener.new_flag = _CFUNC_NEW_FLAG(listener.new_flag) clistener.new_property = _CFUNC_NEW_PROPERTY(value_converter) clistener.end_struct = _CFUNC_NEW_STRUCT(listener.end_struct) clistener.error = _CFUNC_NEW_FLAG(listener.error) _lib.TCOD_parser_run(parser, convert_to_ascii(filename), byref(clistener)) else: _lib.TCOD_parser_run(parser, convert_to_ascii(filename), 0) _lib.TCOD_parser_delete.restype=c_void _lib.TCOD_parser_delete.argtypes=[c_void_p ] def parser_delete(parser): _lib.TCOD_parser_delete(parser) _lib.TCOD_parser_has_property.restype = c_bool _lib.TCOD_parser_has_property.argtypes=[c_void_p, c_char_p] def parser_has_property(parser, name): return _lib.TCOD_parser_has_property(parser, convert_to_ascii(name)) _lib.TCOD_parser_get_bool_property.restype=c_bool _lib.TCOD_parser_get_bool_property.argtypes=[c_void_p , c_char_p] def parser_get_bool_property(parser, name): return _lib.TCOD_parser_get_bool_property(parser, convert_to_ascii(name)) _lib.TCOD_parser_get_int_property.restype=c_int _lib.TCOD_parser_get_int_property.argtypes=[c_void_p , c_char_p] def parser_get_int_property(parser, name): return _lib.TCOD_parser_get_int_property(parser, convert_to_ascii(name)) _lib.TCOD_parser_get_char_property.restype=c_int _lib.TCOD_parser_get_char_property.argtypes=[c_void_p , c_char_p] def parser_get_char_property(parser, name): return '%c' % _lib.TCOD_parser_get_char_property(parser, convert_to_ascii(name)) _lib.TCOD_parser_get_float_property.restype=c_float _lib.TCOD_parser_get_float_property.argtypes=[c_void_p , c_char_p] def parser_get_float_property(parser, name): return _lib.TCOD_parser_get_float_property(parser, convert_to_ascii(name)) _lib.TCOD_parser_get_string_property.restype=c_char_p _lib.TCOD_parser_get_string_property.argtypes=[c_void_p , c_char_p] def parser_get_string_property(parser, name): ret = _lib.TCOD_parser_get_string_property(parser, convert_to_ascii(name)) if is_python_3: return ret.decode("utf-8") return ret _lib.TCOD_parser_get_color_property.restype = Color _lib.TCOD_parser_get_color_property.argtypes=[c_void_p , c_char_p] def parser_get_color_property(parser, name): return _lib.TCOD_parser_get_color_property(parser, convert_to_ascii(name)) _lib.TCOD_parser_get_dice_property_py.argtypes=[c_void_p,c_char_p,POINTER(Dice)] def parser_get_dice_property(parser, name): d = Dice() _lib.TCOD_parser_get_dice_property_py(parser, convert_to_ascii(name), byref(d)) return d _lib.TCOD_parser_get_list_property.restype=c_void_p _lib.TCOD_parser_get_list_property.argtypes=[c_void_p , c_char_p, c_int ] def parser_get_list_property(parser, name, typ): clist = _lib.TCOD_parser_get_list_property(parser, convert_to_ascii(name), typ) return _convert_TCODList(clist, typ) _lib.TCOD_parser_get_custom_property.restype=c_void_p _lib.TCOD_parser_get_custom_property.argtypes=[c_void_p , c_char_p] ############################ # random module ############################ RNG_MT = 0 RNG_CMWC = 1 DISTRIBUTION_LINEAR = 0 DISTRIBUTION_GAUSSIAN = 1 DISTRIBUTION_GAUSSIAN_RANGE = 2 DISTRIBUTION_GAUSSIAN_INVERSE = 3 DISTRIBUTION_GAUSSIAN_RANGE_INVERSE = 4 _lib.TCOD_random_get_instance.restype=c_void_p _lib.TCOD_random_get_instance.argtypes=[] def random_get_instance(): return _lib.TCOD_random_get_instance() _lib.TCOD_random_new.restype=c_void_p _lib.TCOD_random_new.argtypes=[c_int ] def random_new(algo=RNG_CMWC): return _lib.TCOD_random_new(algo) _lib.TCOD_random_new_from_seed.restype=c_void_p _lib.TCOD_random_new_from_seed.argtypes=[c_int, c_uint] def random_new_from_seed(seed, algo=RNG_CMWC): return _lib.TCOD_random_new_from_seed(algo, seed) _lib.TCOD_random_set_distribution.restype=c_void _lib.TCOD_random_set_distribution.argtypes=[c_void_p , c_int ] def random_set_distribution(rnd, dist) : _lib.TCOD_random_set_distribution(rnd, dist) _lib.TCOD_random_get_int.restype=c_int _lib.TCOD_random_get_int.argtypes=[c_void_p , c_int, c_int] def random_get_int(rnd, mi, ma): return _lib.TCOD_random_get_int(rnd, mi, ma) _lib.TCOD_random_get_float.restype=c_float _lib.TCOD_random_get_float.argtypes=[c_void_p , c_float , c_float ] def random_get_float(rnd, mi, ma): return _lib.TCOD_random_get_float(rnd, mi, ma) _lib.TCOD_random_get_double.restype=c_double _lib.TCOD_random_get_double.argtypes=[c_void_p , c_double , c_double ] def random_get_double(rnd, mi, ma): return _lib.TCOD_random_get_double(rnd, mi, ma) _lib.TCOD_random_get_int_mean.restype=c_int _lib.TCOD_random_get_int_mean.argtypes=[c_void_p , c_int, c_int, c_int] def random_get_int_mean(rnd, mi, ma, mean): return _lib.TCOD_random_get_int_mean(rnd, mi, ma, mean) _lib.TCOD_random_get_float_mean.restype=c_float _lib.TCOD_random_get_float_mean.argtypes=[c_void_p , c_float , c_float , c_float ] def random_get_float_mean(rnd, mi, ma, mean): return _lib.TCOD_random_get_float_mean(rnd, mi, ma, mean) _lib.TCOD_random_get_double_mean.restype=c_double _lib.TCOD_random_get_double_mean.argtypes=[c_void_p , c_double , c_double , c_double ] def random_get_double_mean(rnd, mi, ma, mean): return _lib.TCOD_random_get_double_mean(rnd, mi, ma, mean) _lib.TCOD_random_dice_roll_s.restype=c_int _lib.TCOD_random_dice_roll_s.argtypes=[c_void_p , c_char_p ] def random_dice_roll_s(rnd, s): return _lib.TCOD_random_dice_roll_s(rnd, convert_to_ascii(s)) _lib.TCOD_random_save.restype=c_void_p _lib.TCOD_random_save.argtypes=[c_void_p ] def random_save(rnd): return _lib.TCOD_random_save(rnd) _lib.TCOD_random_restore.restype=c_void _lib.TCOD_random_restore.argtypes=[c_void_p , c_void_p ] def random_restore(rnd, backup): _lib.TCOD_random_restore(rnd, backup) _lib.TCOD_random_delete.restype=c_void _lib.TCOD_random_delete.argtypes=[c_void_p ] def random_delete(rnd): _lib.TCOD_random_delete(rnd) ############################ # noise module ############################ NOISE_DEFAULT_HURST = 0.5 NOISE_DEFAULT_LACUNARITY = 2.0 NOISE_DEFAULT = 0 NOISE_PERLIN = 1 NOISE_SIMPLEX = 2 NOISE_WAVELET = 4 _NOISE_PACKER_FUNC = (None, (c_float * 1), (c_float * 2), (c_float * 3), (c_float * 4), ) _lib.TCOD_noise_new.restype=c_void_p _lib.TCOD_noise_new.argtypes=[c_int, c_float , c_float , c_void_p ] def noise_new(dim, h=NOISE_DEFAULT_HURST, l=NOISE_DEFAULT_LACUNARITY, random=0): return _lib.TCOD_noise_new(dim, h, l, random) _lib.TCOD_noise_set_type.restype=c_void _lib.TCOD_noise_set_type.argtypes=[c_void_p , c_int ] def noise_set_type(n, typ) : _lib.TCOD_noise_set_type(n,typ) _lib.TCOD_noise_get.restype=c_float _lib.TCOD_noise_get.argtypes=[c_void_p , POINTER(c_float)] _lib.TCOD_noise_get_ex.restype=c_float _lib.TCOD_noise_get_ex.argtypes=[c_void_p , POINTER(c_float), c_int ] def noise_get(n, f, typ=NOISE_DEFAULT): return _lib.TCOD_noise_get_ex(n, _NOISE_PACKER_FUNC[len(f)](*f), typ) _lib.TCOD_noise_get_fbm.restype=c_float _lib.TCOD_noise_get_fbm.argtypes=[c_void_p , POINTER(c_float), c_float ] _lib.TCOD_noise_get_fbm_ex.restype=c_float _lib.TCOD_noise_get_fbm_ex.argtypes=[c_void_p , POINTER(c_float), c_float , c_int ] def noise_get_fbm(n, f, oc, typ=NOISE_DEFAULT): return _lib.TCOD_noise_get_fbm_ex(n, _NOISE_PACKER_FUNC[len(f)](*f), oc, typ) _lib.TCOD_noise_get_turbulence.restype=c_float _lib.TCOD_noise_get_turbulence.argtypes=[c_void_p , POINTER(c_float), c_float ] _lib.TCOD_noise_get_turbulence_ex.restype=c_float _lib.TCOD_noise_get_turbulence_ex.argtypes=[c_void_p , POINTER(c_float), c_float , c_int ] def noise_get_turbulence(n, f, oc, typ=NOISE_DEFAULT): return _lib.TCOD_noise_get_turbulence_ex(n, _NOISE_PACKER_FUNC[len(f)](*f), oc, typ) _lib.TCOD_noise_delete.restype=c_void _lib.TCOD_noise_delete.argtypes=[c_void_p ] def noise_delete(n): _lib.TCOD_noise_delete(n) ############################ # fov module ############################ _lib.TCOD_map_is_in_fov.restype = c_bool _lib.TCOD_map_is_transparent.restype = c_bool _lib.TCOD_map_is_walkable.restype = c_bool FOV_BASIC = 0 FOV_DIAMOND = 1 FOV_SHADOW = 2 FOV_PERMISSIVE_0 = 3 FOV_PERMISSIVE_1 = 4 FOV_PERMISSIVE_2 = 5 FOV_PERMISSIVE_3 = 6 FOV_PERMISSIVE_4 = 7 FOV_PERMISSIVE_5 = 8 FOV_PERMISSIVE_6 = 9 FOV_PERMISSIVE_7 = 10 FOV_PERMISSIVE_8 = 11 FOV_RESTRICTIVE = 12 NB_FOV_ALGORITHMS = 13 def FOV_PERMISSIVE(p) : return FOV_PERMISSIVE_0+p _lib.TCOD_map_new.restype=c_void_p _lib.TCOD_map_new.argtypes=[c_int, c_int] def map_new(w, h): return _lib.TCOD_map_new(w, h) _lib.TCOD_map_copy.restype=c_void _lib.TCOD_map_copy.argtypes=[c_void_p , c_void_p ] def map_copy(source, dest): return _lib.TCOD_map_copy(source, dest) _lib.TCOD_map_set_properties.restype=c_void _lib.TCOD_map_set_properties.argtypes=[c_void_p , c_int, c_int, c_bool, c_bool] def map_set_properties(m, x, y, isTrans, isWalk): _lib.TCOD_map_set_properties(m, x, y, c_int(isTrans), c_int(isWalk)) _lib.TCOD_map_clear.restype=c_void _lib.TCOD_map_clear.argtypes=[c_void_p , c_bool , c_bool ] def map_clear(m,walkable=False,transparent=False): _lib.TCOD_map_clear(m,c_int(walkable),c_int(transparent)) _lib.TCOD_map_compute_fov.restype=c_void _lib.TCOD_map_compute_fov.argtypes=[c_void_p , c_int, c_int, c_int, c_bool, c_int ] def map_compute_fov(m, x, y, radius=0, light_walls=True, algo=FOV_RESTRICTIVE ): _lib.TCOD_map_compute_fov(m, x, y, c_int(radius), c_bool(light_walls), c_int(algo)) _lib.TCOD_map_set_in_fov.restype=c_void _lib.TCOD_map_set_in_fov.argtypes=[c_void_p , c_int, c_int, c_bool ] def map_set_in_fov(m, x, y, fov): return _lib.TCOD_map_set_in_fov(m, x, y, fov) _lib.TCOD_map_is_in_fov.restype=c_bool _lib.TCOD_map_is_in_fov.argtypes=[c_void_p , c_int, c_int] def map_is_in_fov(m, x, y): return _lib.TCOD_map_is_in_fov(m, x, y) _lib.TCOD_map_is_transparent.restype=c_bool _lib.TCOD_map_is_transparent.argtypes=[c_void_p , c_int, c_int] def map_is_transparent(m, x, y): return _lib.TCOD_map_is_transparent(m, x, y) _lib.TCOD_map_is_walkable.restype=c_bool _lib.TCOD_map_is_walkable.argtypes=[c_void_p , c_int, c_int] def map_is_walkable(m, x, y): return _lib.TCOD_map_is_walkable(m, x, y) _lib.TCOD_map_delete.restype=c_void _lib.TCOD_map_delete.argtypes=[c_void_p ] def map_delete(m): return _lib.TCOD_map_delete(m) _lib.TCOD_map_get_width.restype=c_int _lib.TCOD_map_get_width.argtypes=[c_void_p ] def map_get_width(map): return _lib.TCOD_map_get_width(map) _lib.TCOD_map_get_height.restype=c_int _lib.TCOD_map_get_height.argtypes=[c_void_p ] def map_get_height(map): return _lib.TCOD_map_get_height(map) _lib.TCOD_map_get_nb_cells.restype=c_int _lib.TCOD_map_get_nb_cells.argtypes=[c_void_p ] def map_get_nb_cells(map): return TCOD_map_get_nb_cells(map) ############################ # pathfinding module ############################ PATH_CBK_FUNC = CFUNCTYPE(c_float, c_int, c_int, c_int, c_int, py_object) _lib.TCOD_path_new_using_map.restype=c_void_p _lib.TCOD_path_new_using_map.argtypes=[c_void_p , c_float ] def path_new_using_map(m, dcost=1.41): return (_lib.TCOD_path_new_using_map(m, dcost), None) _lib.TCOD_path_new_using_function.restype=c_void_p _lib.TCOD_path_new_using_function.argtypes=[c_int, c_int, PATH_CBK_FUNC, py_object, c_float] def path_new_using_function(w, h, func, userdata=0, dcost=1.41): cbk_func = PATH_CBK_FUNC(func) return (_lib.TCOD_path_new_using_function(w, h, cbk_func, userdata, dcost), cbk_func) _lib.TCOD_path_compute.restype = c_bool _lib.TCOD_path_compute.argtypes=[c_void_p , c_int,c_int, c_int, c_int] def path_compute(p, ox, oy, dx, dy): return _lib.TCOD_path_compute(p[0], ox, oy, dx, dy) _lib.TCOD_path_get_origin.restype=c_void _lib.TCOD_path_get_origin.argtypes=[c_void_p , POINTER(c_int), POINTER(c_int)] def path_get_origin(p): x = c_int() y = c_int() _lib.TCOD_path_get_origin(p[0], byref(x), byref(y)) return x.value, y.value _lib.TCOD_path_get_destination.restype=c_void _lib.TCOD_path_get_destination.argtypes=[c_void_p , POINTER(c_int), POINTER(c_int)] def path_get_destination(p): x = c_int() y = c_int() _lib.TCOD_path_get_destination(p[0], byref(x), byref(y)) return x.value, y.value _lib.TCOD_path_size.restype=c_int _lib.TCOD_path_size.argtypes=[c_void_p ] def path_size(p): return _lib.TCOD_path_size(p[0]) _lib.TCOD_path_reverse.restype=c_void _lib.TCOD_path_reverse.argtypes=[c_void_p ] def path_reverse(p): _lib.TCOD_path_reverse(p[0]) _lib.TCOD_path_get.restype=c_void _lib.TCOD_path_get.argtypes=[c_void_p , c_int, POINTER(c_int), POINTER(c_int)] def path_get(p, idx): x = c_int() y = c_int() _lib.TCOD_path_get(p[0], idx, byref(x), byref(y)) return x.value, y.value _lib.TCOD_path_is_empty.restype = c_bool _lib.TCOD_path_is_empty.argtypes=[c_void_p ] def path_is_empty(p): return _lib.TCOD_path_is_empty(p[0]) _lib.TCOD_path_walk.restype = c_bool _lib.TCOD_path_walk.argtypes=[c_void_p , POINTER(c_int), POINTER(c_int), c_bool] def path_walk(p, recompute): x = c_int() y = c_int() if _lib.TCOD_path_walk(p[0], byref(x), byref(y), c_int(recompute)): return x.value, y.value return None,None _lib.TCOD_path_delete.restype=c_void _lib.TCOD_path_delete.argtypes=[c_void_p ] def path_delete(p): _lib.TCOD_path_delete(p[0]) _lib.TCOD_dijkstra_new .restype=c_void_p _lib.TCOD_dijkstra_new .argtypes=[c_void_p , c_float ] def dijkstra_new(m, dcost=1.41): return (_lib.TCOD_dijkstra_new(c_void_p(m), c_float(dcost)), None) _lib.TCOD_dijkstra_new_using_function.restype=c_void_p _lib.TCOD_dijkstra_new_using_function.argtypes=[c_int, c_int, PATH_CBK_FUNC, py_object, c_float] def dijkstra_new_using_function(w, h, func, userdata=0, dcost=1.41): cbk_func = PATH_CBK_FUNC(func) return (_lib.TCOD_dijkstra_new_using_function(w, h, cbk_func, userdata, dcost), cbk_func) _lib.TCOD_dijkstra_compute.restype=c_void _lib.TCOD_dijkstra_compute.argtypes=[c_void_p , c_int, c_int] def dijkstra_compute(p, ox, oy): _lib.TCOD_dijkstra_compute(p[0], c_int(ox), c_int(oy)) _lib.TCOD_dijkstra_path_set.restype = c_bool _lib.TCOD_dijkstra_path_set .argtypes=[c_void_p , c_int, c_int] def dijkstra_path_set(p, x, y): return _lib.TCOD_dijkstra_path_set(p[0], c_int(x), c_int(y)) _lib.TCOD_dijkstra_get_distance.restype = c_float _lib.TCOD_dijkstra_get_distance.argtypes=[c_void_p , c_int, c_int] def dijkstra_get_distance(p, x, y): return _lib.TCOD_dijkstra_get_distance(p[0], c_int(x), c_int(y)) _lib.TCOD_dijkstra_size.restype=c_int _lib.TCOD_dijkstra_size.argtypes=[c_void_p ] def dijkstra_size(p): return _lib.TCOD_dijkstra_size(p[0]) _lib.TCOD_dijkstra_reverse.restype=c_void _lib.TCOD_dijkstra_reverse.argtypes=[c_void_p ] def dijkstra_reverse(p): _lib.TCOD_dijkstra_reverse(p[0]) _lib.TCOD_dijkstra_get.restype=c_void _lib.TCOD_dijkstra_get.argtypes=[c_void_p , c_int, POINTER(c_int), POINTER(c_int)] def dijkstra_get(p, idx): x = c_int() y = c_int() _lib.TCOD_dijkstra_get(p[0], c_int(idx), byref(x), byref(y)) return x.value, y.value _lib.TCOD_dijkstra_is_empty.restype = c_bool _lib.TCOD_dijkstra_is_empty.argtypes=[c_void_p ] def dijkstra_is_empty(p): return _lib.TCOD_dijkstra_is_empty(p[0]) _lib.TCOD_dijkstra_path_walk.restype = c_bool _lib.TCOD_dijkstra_path_walk.argtypes=[c_void_p , POINTER(c_int), POINTER(c_int)] def dijkstra_path_walk(p): x = c_int() y = c_int() if _lib.TCOD_dijkstra_path_walk(p[0], byref(x), byref(y)): return x.value, y.value return None,None _lib.TCOD_dijkstra_delete .restype=c_void _lib.TCOD_dijkstra_delete.argtypes=[c_void_p ] def dijkstra_delete(p): _lib.TCOD_dijkstra_delete(p[0]) ############################ # bsp module ############################ class _CBsp(Structure): _fields_ = [('next', c_void_p), ('father', c_void_p), ('son', c_void_p), ('x', c_int), ('y', c_int), ('w', c_int), ('h', c_int), ('position', c_int), ('level', c_uint8), ('horizontal', c_bool), ] BSP_CBK_FUNC = CFUNCTYPE(c_int, c_void_p, c_void_p) # Python class encapsulating the _CBsp pointer class Bsp(object): def __init__(self, cnode): pcbsp = cast(cnode, POINTER(_CBsp)) self.p = pcbsp def getx(self): return self.p.contents.x def setx(self, value): self.p.contents.x = value x = property(getx, setx) def gety(self): return self.p.contents.y def sety(self, value): self.p.contents.y = value y = property(gety, sety) def getw(self): return self.p.contents.w def setw(self, value): self.p.contents.w = value w = property(getw, setw) def geth(self): return self.p.contents.h def seth(self, value): self.p.contents.h = value h = property(geth, seth) def getpos(self): return self.p.contents.position def setpos(self, value): self.p.contents.position = value position = property(getpos, setpos) def gethor(self): return self.p.contents.horizontal def sethor(self,value): self.p.contents.horizontal = value horizontal = property(gethor, sethor) def getlev(self): return self.p.contents.level def setlev(self,value): self.p.contents.level = value level = property(getlev, setlev) _lib.TCOD_bsp_new.restype=c_void_p _lib.TCOD_bsp_new.argtypes=[c_int, c_int, c_int, c_int] def bsp_new(x, y, w, h): return _lib.TCOD_bsp_new(x, y, w, h) _lib.TCOD_bsp_new_with_size.restype = POINTER(_CBsp) _lib.TCOD_bsp_new_with_size.argtypes=[c_int,c_int,c_int, c_int] def bsp_new_with_size(x, y, w, h): return Bsp(_lib.TCOD_bsp_new_with_size(x, y, w, h)) _lib.TCOD_bsp_split_once.restype=c_void _lib.TCOD_bsp_split_once.argtypes=[c_void_p, c_bool , c_int] def bsp_split_once(node, horizontal, position): _lib.TCOD_bsp_split_once(node.p, c_int(horizontal), position) _lib.TCOD_bsp_split_recursive.restype=c_void _lib.TCOD_bsp_split_recursive.argtypes=[c_void_p, c_void_p , c_int, ] def bsp_split_recursive(node, randomizer, nb, minHSize, minVSize, maxHRatio, maxVRatio): _lib.TCOD_bsp_split_recursive(node.p, randomizer, nb, minHSize, minVSize, c_float(maxHRatio), c_float(maxVRatio)) _lib.TCOD_bsp_resize.restype=c_void _lib.TCOD_bsp_resize.argtypes=[c_void_p, c_int,c_int, c_int, c_int] def bsp_resize(node, x, y, w, h): _lib.TCOD_bsp_resize(node.p, x, y, w, h) _lib.TCOD_bsp_left.restype = POINTER(_CBsp) _lib.TCOD_bsp_left.argtypes=[c_void_p] def bsp_left(node): return Bsp(_lib.TCOD_bsp_left(node.p)) _lib.TCOD_bsp_right.restype = POINTER(_CBsp) _lib.TCOD_bsp_right.argtypes=[c_void_p] def bsp_right(node): return Bsp(_lib.TCOD_bsp_right(node.p)) _lib.TCOD_bsp_father.restype = POINTER(_CBsp) _lib.TCOD_bsp_father.argtypes=[c_void_p] def bsp_father(node): return Bsp(_lib.TCOD_bsp_father(node.p)) _lib.TCOD_bsp_is_leaf.restype = c_bool _lib.TCOD_bsp_is_leaf.argtypes=[c_void_p] def bsp_is_leaf(node): return _lib.TCOD_bsp_is_leaf(node.p) _lib.TCOD_bsp_contains.restype = c_bool _lib.TCOD_bsp_contains.argtypes=[c_void_p, c_int, c_int] def bsp_contains(node, cx, cy): return _lib.TCOD_bsp_contains(node.p, cx, cy) _lib.TCOD_bsp_find_node.restype = POINTER(_CBsp) _lib.TCOD_bsp_find_node.argtypes=[c_void_p, c_int, c_int] def bsp_find_node(node, cx, cy): return Bsp(_lib.TCOD_bsp_find_node(node.p, cx, cy)) def _bsp_traverse(node, callback, userData, func): # convert the c node into a Python node #before passing it to the actual callback def node_converter(cnode, data): node = Bsp(cnode) return callback(node, data) cbk_func = BSP_CBK_FUNC(node_converter) func(node.p, cbk_func, userData) def bsp_traverse_pre_order(node, callback, userData=0): _bsp_traverse(node, callback, userData, _lib.TCOD_bsp_traverse_pre_order) def bsp_traverse_in_order(node, callback, userData=0): _bsp_traverse(node, callback, userData, _lib.TCOD_bsp_traverse_in_order) def bsp_traverse_post_order(node, callback, userData=0): _bsp_traverse(node, callback, userData, _lib.TCOD_bsp_traverse_post_order) def bsp_traverse_level_order(node, callback, userData=0): _bsp_traverse(node, callback, userData, _lib.TCOD_bsp_traverse_level_order) def bsp_traverse_inverted_level_order(node, callback, userData=0): _bsp_traverse(node, callback, userData, _lib.TCOD_bsp_traverse_inverted_level_order) _lib.TCOD_bsp_remove_sons.restype=c_void _lib.TCOD_bsp_remove_sons.argtypes=[c_void_p] def bsp_remove_sons(node): _lib.TCOD_bsp_remove_sons(node.p) _lib.TCOD_bsp_delete.restype=c_void _lib.TCOD_bsp_delete.argtypes=[c_void_p] def bsp_delete(node): _lib.TCOD_bsp_delete(node.p) ############################ # heightmap module ############################ class _CHeightMap(Structure): _fields_=[('w', c_int), ('h', c_int), ('values', POINTER(c_float)), ] class HeightMap(object): def __init__(self, chm): pchm = cast(chm, POINTER(_CHeightMap)) self.p = pchm def getw(self): return self.p.contents.w def setw(self, value): self.p.contents.w = value w = property(getw, setw) def geth(self): return self.p.contents.h def seth(self, value): self.p.contents.h = value h = property(geth, seth) _lib.TCOD_heightmap_new.restype = POINTER(_CHeightMap) _lib.TCOD_heightmap_new.argtypes=[c_int,c_int] def heightmap_new(w, h): phm = _lib.TCOD_heightmap_new(w, h) return HeightMap(phm) _lib.TCOD_heightmap_set_value.restype=c_void _lib.TCOD_heightmap_set_value.argtypes=[c_void_p, c_int, c_int, c_float ] def heightmap_set_value(hm, x, y, value): _lib.TCOD_heightmap_set_value(hm.p, x, y, c_float(value)) _lib.TCOD_heightmap_add.restype=c_void _lib.TCOD_heightmap_add.argtypes=[c_void_p, c_float ] def heightmap_add(hm, value): _lib.TCOD_heightmap_add(hm.p, c_float(value)) _lib.TCOD_heightmap_scale.restype=c_void _lib.TCOD_heightmap_scale.argtypes=[c_void_p, c_float ] def heightmap_scale(hm, value): _lib.TCOD_heightmap_scale(hm.p, c_float(value)) _lib.TCOD_heightmap_clear.restype=c_void _lib.TCOD_heightmap_clear.argtypes=[c_void_p] def heightmap_clear(hm): _lib.TCOD_heightmap_clear(hm.p) _lib.TCOD_heightmap_clamp.restype=c_void _lib.TCOD_heightmap_clamp.argtypes=[c_void_p, c_float , c_float ] def heightmap_clamp(hm, mi, ma): _lib.TCOD_heightmap_clamp(hm.p, c_float(mi),c_float(ma)) _lib.TCOD_heightmap_copy.restype=c_void _lib.TCOD_heightmap_copy.argtypes=[c_void_p,c_void_p] def heightmap_copy(hm1, hm2): _lib.TCOD_heightmap_copy(hm1.p, hm2.p) _lib.TCOD_heightmap_normalize.restype=c_void _lib.TCOD_heightmap_normalize.argtypes=[c_void_p, c_float , c_float ] def heightmap_normalize(hm, mi=0.0, ma=1.0): _lib.TCOD_heightmap_normalize(hm.p, c_float(mi), c_float(ma)) _lib.TCOD_heightmap_lerp_hm.restype=c_void _lib.TCOD_heightmap_lerp_hm.argtypes=[c_void_p, c_void_p, c_void_p, c_float ] def heightmap_lerp_hm(hm1, hm2, hm3, coef): _lib.TCOD_heightmap_lerp_hm(hm1.p, hm2.p, hm3.p, c_float(coef)) _lib.TCOD_heightmap_add_hm.restype=c_void _lib.TCOD_heightmap_add_hm.argtypes=[c_void_p, c_void_p, c_void_p] def heightmap_add_hm(hm1, hm2, hm3): _lib.TCOD_heightmap_add_hm(hm1.p, hm2.p, hm3.p) _lib.TCOD_heightmap_multiply_hm.restype=c_void _lib.TCOD_heightmap_multiply_hm.argtypes=[c_void_p, c_void_p, c_void_p] def heightmap_multiply_hm(hm1, hm2, hm3): _lib.TCOD_heightmap_multiply_hm(hm1.p, hm2.p, hm3.p) _lib.TCOD_heightmap_add_hill.restype=c_void _lib.TCOD_heightmap_add_hill.argtypes=[c_void_p, c_float , c_float , c_float , c_float ] def heightmap_add_hill(hm, x, y, radius, height): _lib.TCOD_heightmap_add_hill(hm.p, c_float( x), c_float( y), c_float( radius), c_float( height)) _lib.TCOD_heightmap_dig_hill.restype=c_void _lib.TCOD_heightmap_dig_hill.argtypes=[c_void_p, c_float , c_float , c_float , c_float ] def heightmap_dig_hill(hm, x, y, radius, height): _lib.TCOD_heightmap_dig_hill(hm.p, c_float( x), c_float( y), c_float( radius), c_float( height)) _lib.TCOD_heightmap_mid_point_displacement.restype = c_void _lib.TCOD_heightmap_mid_point_displacement.argtypes = [c_void_p, c_void_p, c_float] def heightmap_mid_point_displacement(hm, rng, roughness): _lib.TCOD_heightmap_mid_point_displacement(hm.p, rng, roughness) _lib.TCOD_heightmap_rain_erosion.restype=c_void _lib.TCOD_heightmap_rain_erosion.argtypes=[c_void_p, c_int,c_float ,c_float ,c_void_p ] def heightmap_rain_erosion(hm, nbDrops, erosionCoef, sedimentationCoef, rnd=0): _lib.TCOD_heightmap_rain_erosion(hm.p, nbDrops, c_float( erosionCoef), c_float( sedimentationCoef), rnd) _lib.TCOD_heightmap_kernel_transform.restype=c_void _lib.TCOD_heightmap_kernel_transform.argtypes=[c_void_p, c_int, POINTER(c_int), POINTER(c_int), POINTER(c_float), c_float ,c_float ] def heightmap_kernel_transform(hm, kernelsize, dx, dy, weight, minLevel, maxLevel): FARRAY = c_float * kernelsize IARRAY = c_int * kernelsize cdx = IARRAY(*dx) cdy = IARRAY(*dy) cweight = FARRAY(*weight) _lib.TCOD_heightmap_kernel_transform(hm.p, kernelsize, cdx, cdy, cweight, c_float(minLevel), c_float(maxLevel)) _lib.TCOD_heightmap_add_voronoi.restype=c_void _lib.TCOD_heightmap_add_voronoi.argtypes=[c_void_p, c_int, c_int, POINTER(c_float),c_void_p ] def heightmap_add_voronoi(hm, nbPoints, nbCoef, coef, rnd=0): FARRAY = c_float * nbCoef ccoef = FARRAY(*coef) _lib.TCOD_heightmap_add_voronoi(hm.p, nbPoints, nbCoef, ccoef, rnd) _lib.TCOD_heightmap_add_fbm.restype=c_void _lib.TCOD_heightmap_add_fbm.argtypes=[c_void_p, c_void_p, c_float, c_float, c_float, c_float, c_float, c_float, c_float] def heightmap_add_fbm(hm, noise, mulx, muly, addx, addy, octaves, delta, scale): _lib.TCOD_heightmap_add_fbm(hm.p, noise, c_float(mulx), c_float(muly), c_float(addx), c_float(addy), c_float(octaves), c_float(delta), c_float(scale)) _lib.TCOD_heightmap_scale_fbm.restype=c_void _lib.TCOD_heightmap_scale_fbm.argtypes=[c_void_p, c_void_p, c_float, c_float, c_float, c_float, c_float, c_float, c_float] def heightmap_scale_fbm(hm, noise, mulx, muly, addx, addy, octaves, delta, scale): _lib.TCOD_heightmap_scale_fbm(hm.p, noise, c_float(mulx), c_float(muly), c_float(addx), c_float(addy), c_float(octaves), c_float(delta), c_float(scale)) _lib.TCOD_heightmap_islandify.restype=c_void _lib.TCOD_heightmap_islandify.argtypes=[c_void_p, c_float ,c_void_p ] def heightmap_islandify(hm, sealevel, rnd): return TCOD_heightmap_islandify(hm, sealevel, rnd) _lib.TCOD_heightmap_dig_bezier.restype=c_void _lib.TCOD_heightmap_dig_bezier.argtypes=[c_void_p, POINTER(c_int), POINTER(c_int), c_float , c_float , c_float , c_float ] def heightmap_dig_bezier(hm, px, py, startRadius, startDepth, endRadius, endDepth): IARRAY = c_int * 4 cpx = IARRAY(*px) cpy = IARRAY(*py) _lib.TCOD_heightmap_dig_bezier(hm.p, cpx, cpy, c_float(startRadius), c_float(startDepth), c_float(endRadius), c_float(endDepth)) _lib.TCOD_heightmap_get_value.restype = c_float _lib.TCOD_heightmap_get_value.argtypes=[c_void_p, c_int, c_int] def heightmap_get_value(hm, x, y): return _lib.TCOD_heightmap_get_value(hm.p, x, y) _lib.TCOD_heightmap_get_interpolated_value.restype=c_float _lib.TCOD_heightmap_get_interpolated_value.argtypes=[c_void_p, c_float , c_float ] def heightmap_get_interpolated_value(hm, x, y): return _lib.TCOD_heightmap_get_interpolated_value(hm.p, c_float(x), c_float(y)) _lib.TCOD_heightmap_get_slope.restype=c_float _lib.TCOD_heightmap_get_slope.argtypes=[c_void_p, c_int, c_int] def heightmap_get_slope(hm, x, y): return _lib.TCOD_heightmap_get_slope(hm.p, x, y) _lib.TCOD_heightmap_get_normal.restype=c_void _lib.TCOD_heightmap_get_normal.argtypes=[c_void_p, c_float , c_float , POINTER(c_float), c_float ] def heightmap_get_normal(hm, x, y, waterLevel): FARRAY = c_float * 3 cn = FARRAY() _lib.TCOD_heightmap_get_normal(hm.p, c_float(x), c_float(y), cn, c_float(waterLevel)) return cn[0], cn[1], cn[2] _lib.TCOD_heightmap_count_cells.restype=c_int _lib.TCOD_heightmap_count_cells.argtypes=[c_void_p, c_float , c_float ] def heightmap_count_cells(hm, mi, ma): return _lib.TCOD_heightmap_count_cells(hm.p, c_float(mi), c_float(ma)) _lib.TCOD_heightmap_has_land_on_border.restype = c_bool _lib.TCOD_heightmap_has_land_on_border.argtypes=[c_void_p, c_float ] def heightmap_has_land_on_border(hm, waterlevel): return _lib.TCOD_heightmap_has_land_on_border(hm.p, c_float(waterlevel)) _lib.TCOD_heightmap_get_minmax.restype=c_void _lib.TCOD_heightmap_get_minmax.argtypes=[c_void_p, POINTER(c_float), POINTER(c_float)] def heightmap_get_minmax(hm): mi = c_float() ma = c_float() _lib.TCOD_heightmap_get_minmax(hm.p, byref(mi), byref(ma)) return mi.value, ma.value _lib.TCOD_heightmap_delete.restype=c_void _lib.TCOD_heightmap_delete.argtypes=[c_void_p] def heightmap_delete(hm): _lib.TCOD_heightmap_delete(hm.p) ############################ # name generator module ############################ _lib.TCOD_namegen_parse.restype=c_void _lib.TCOD_namegen_parse.argtypes=[c_char_p , c_void_p ] def namegen_parse(filename,rnd=0) : _lib.TCOD_namegen_parse(convert_to_ascii(filename),rnd) _lib.TCOD_namegen_generate.restype=c_char_p _lib.TCOD_namegen_generate.argtypes=[c_char_p , c_bool ] def namegen_generate(name) : ret = _lib.TCOD_namegen_generate(convert_to_ascii(name), 0) if is_python_3: return ret.decode("utf-8") return ret _lib.TCOD_namegen_generate_custom.restype=c_char_p _lib.TCOD_namegen_generate_custom.argtypes=[c_char_p , c_char_p , c_bool ] def namegen_generate_custom(name, rule) : ret = _lib.TCOD_namegen_generate(convert_to_ascii(name), convert_to_ascii(rule), 0) if is_python_3: return ret.decode("utf-8") return ret _lib.TCOD_namegen_get_sets.restype=c_void_p _lib.TCOD_namegen_get_sets.argtypes=[] def namegen_get_sets(): nb=_lib.TCOD_namegen_get_nb_sets_wrapper() SARRAY = c_char_p * nb; setsa = SARRAY() _lib.TCOD_namegen_get_sets_wrapper(setsa) if is_python_3: return list(v.decode("utf-8") for v in setsa) return list(setsa) _lib.TCOD_namegen_destroy.restype=c_void _lib.TCOD_namegen_destroy.argtypes=[] def namegen_destroy() : _lib.TCOD_namegen_destroy() _lib.TCOD_lex_new_intern.restype=c_void_p _lib.TCOD_lex_new_intern.argtypes=[] _lib.TCOD_lex_new.restype=c_void_p _lib.TCOD_lex_new.argtypes=[POINTER(c_char_p), POINTER(c_char_p), c_char_p, ] _lib.TCOD_lex_delete.restype=c_void _lib.TCOD_lex_delete.argtypes=[c_void_p] _lib.TCOD_lex_set_data_buffer.restype=c_void _lib.TCOD_lex_set_data_buffer.argtypes=[c_void_p,c_char_p] _lib.TCOD_lex_set_data_file.restype=c_bool _lib.TCOD_lex_set_data_file.argtypes=[c_void_p,c_char_p] _lib.TCOD_lex_parse.restype=c_int _lib.TCOD_lex_parse.argtypes=[c_void_p] _lib.TCOD_lex_parse_until_token_type.restype=c_int _lib.TCOD_lex_parse_until_token_type.argtypes=[c_void_p,c_int] _lib.TCOD_lex_parse_until_token_value.restype=c_int _lib.TCOD_lex_parse_until_token_value.argtypes=[c_void_p,c_char_p] _lib.TCOD_lex_expect_token_type.restype=c_bool _lib.TCOD_lex_expect_token_type.argtypes=[c_void_p,c_int] _lib.TCOD_lex_expect_token_value.restype=c_bool _lib.TCOD_lex_expect_token_value.argtypes=[c_void_p,c_int,c_char_p] _lib.TCOD_lex_savepoint.restype=c_void _lib.TCOD_lex_savepoint.argtypes=[c_void_p,c_void_p] _lib.TCOD_lex_restore.restype=c_void _lib.TCOD_lex_restore.argtypes=[c_void_p,c_void_p] _lib.TCOD_lex_get_last_javadoc.restype=c_char_p _lib.TCOD_lex_get_last_javadoc.argtypes=[c_void_p] _lib.TCOD_lex_get_token_name.restype=c_char_p _lib.TCOD_lex_get_token_name.argtypes=[c_int] _lib.TCOD_lex_get_last_error.restype=c_char_p _lib.TCOD_lex_get_last_error.argtypes=[] _lib.TCOD_lex_hextoint.restype=c_int _lib.TCOD_lex_hextoint.argtypes=[c_char] _lib.TCOD_sys_get_surface.restype=c_void_p _lib.TCOD_sys_get_surface.argtypes=[c_int, c_int, c_bool ] _lib.TCOD_sys_load_image.restype=c_void_p _lib.TCOD_sys_load_image.argtypes=[c_char_p] _lib.TCOD_list_new.restype=c_void_p _lib.TCOD_list_new.argtypes=[] _lib.TCOD_list_allocate.restype=c_void_p _lib.TCOD_list_allocate.argtypes=[c_int] _lib.TCOD_list_duplicate.restype=c_void_p _lib.TCOD_list_duplicate.argtypes=[c_void_p ] _lib.TCOD_list_delete.restype=c_void _lib.TCOD_list_delete.argtypes=[c_void_p ] _lib.TCOD_list_push.restype=c_void _lib.TCOD_list_push.argtypes=[c_void_p ,c_void_p ] _lib.TCOD_list_pop.restype=c_void_p _lib.TCOD_list_pop.argtypes=[c_void_p ] _lib.TCOD_list_peek.restype=c_void_p _lib.TCOD_list_peek.argtypes=[c_void_p ] _lib.TCOD_list_add_all.restype=c_void _lib.TCOD_list_add_all.argtypes=[c_void_p , c_void_p ] _lib.TCOD_list_get.restype=c_void_p _lib.TCOD_list_get.argtypes=[c_void_p ,c_int] _lib.TCOD_list_set.restype=c_void _lib.TCOD_list_set.argtypes=[c_void_p ,c_void_p, c_int] _lib.TCOD_list_begin.restype=POINTER(c_void_p) _lib.TCOD_list_begin.argtypes=[c_void_p ] _lib.TCOD_list_end.restype=POINTER(c_void_p) _lib.TCOD_list_end.argtypes=[c_void_p ] _lib.TCOD_list_reverse.restype=c_void _lib.TCOD_list_reverse.argtypes=[c_void_p ] _lib.TCOD_list_remove_iterator.restype=POINTER(c_void_p) _lib.TCOD_list_remove_iterator.argtypes=[c_void_p , POINTER(c_void_p)] _lib.TCOD_list_remove.restype=c_void _lib.TCOD_list_remove.argtypes=[c_void_p ,c_void_p ] _lib.TCOD_list_remove_iterator_fast.restype=POINTER(c_void_p) _lib.TCOD_list_remove_iterator_fast.argtypes=[c_void_p , POINTER(c_void_p)] _lib.TCOD_list_remove_fast.restype=c_void _lib.TCOD_list_remove_fast.argtypes=[c_void_p ,c_void_p ] _lib.TCOD_list_contains.restype=c_bool _lib.TCOD_list_contains.argtypes=[c_void_p ,c_void_p ] _lib.TCOD_list_clear.restype=c_void _lib.TCOD_list_clear.argtypes=[c_void_p ] _lib.TCOD_list_clear_and_delete.restype=c_void _lib.TCOD_list_clear_and_delete.argtypes=[c_void_p ] _lib.TCOD_list_size.restype=c_int _lib.TCOD_list_size.argtypes=[c_void_p ] _lib.TCOD_list_insert_before.restype=POINTER(c_void_p) _lib.TCOD_list_insert_before.argtypes=[c_void_p ,c_void_p,c_int] _lib.TCOD_list_is_empty.restype=c_bool _lib.TCOD_list_is_empty.argtypes=[c_void_p ] _lib.TCOD_sys_create_directory.restype=c_bool _lib.TCOD_sys_create_directory.argtypes=[c_char_p] _lib.TCOD_sys_delete_file.restype=c_bool _lib.TCOD_sys_delete_file.argtypes=[c_char_p] _lib.TCOD_sys_delete_directory.restype=c_bool _lib.TCOD_sys_delete_directory.argtypes=[c_char_p] _lib.TCOD_sys_is_directory.restype=c_bool _lib.TCOD_sys_is_directory.argtypes=[c_char_p] _lib.TCOD_sys_get_directory_content.restype=c_void_p _lib.TCOD_sys_get_directory_content.argtypes=[c_char_p, c_char_p] _lib.TCOD_sys_file_exists.restype=c_bool # lib.TCOD_sys_file_exists.argtypes=[c_char_p , ...] _lib.TCOD_sys_get_num_cores.restype=c_int _lib.TCOD_sys_get_num_cores.argtypes=[] _lib.TCOD_thread_wait.restype=c_void _lib.TCOD_thread_wait.argtypes=[c_void_p ] _lib.TCOD_mutex_new.restype=c_void_p _lib.TCOD_mutex_new.argtypes=[] _lib.TCOD_mutex_in.restype=c_void _lib.TCOD_mutex_in.argtypes=[c_void_p ] _lib.TCOD_mutex_out.restype=c_void _lib.TCOD_mutex_out.argtypes=[c_void_p ] _lib.TCOD_mutex_delete.restype=c_void _lib.TCOD_mutex_delete.argtypes=[c_void_p ] _lib.TCOD_semaphore_new.restype=c_void_p _lib.TCOD_semaphore_new.argtypes=[c_int] _lib.TCOD_semaphore_lock.restype=c_void _lib.TCOD_semaphore_lock.argtypes=[c_void_p ] _lib.TCOD_semaphore_unlock.restype=c_void _lib.TCOD_semaphore_unlock.argtypes=[c_void_p ] _lib.TCOD_semaphore_delete.restype=c_void _lib.TCOD_semaphore_delete.argtypes=[ c_void_p ] _lib.TCOD_condition_new.restype=c_void_p _lib.TCOD_condition_new.argtypes=[] _lib.TCOD_condition_signal.restype=c_void _lib.TCOD_condition_signal.argtypes=[c_void_p ] _lib.TCOD_condition_broadcast.restype=c_void _lib.TCOD_condition_broadcast.argtypes=[c_void_p ] _lib.TCOD_condition_wait.restype=c_void _lib.TCOD_condition_wait.argtypes=[c_void_p , c_void_p ] _lib.TCOD_condition_delete.restype=c_void _lib.TCOD_condition_delete.argtypes=[ c_void_p ] _lib.TCOD_tree_new.restype=c_void_p _lib.TCOD_tree_new.argtypes=[] _lib.TCOD_tree_add_son.restype=c_void _lib.TCOD_tree_add_son.argtypes=[c_void_p, c_void_p] _lib.TCOD_text_init.restype=c_void_p _lib.TCOD_text_init.argtypes=[c_int, c_int, c_int, c_int, c_int] _lib.TCOD_text_set_properties.restype=c_void _lib.TCOD_text_set_properties.argtypes=[c_void_p , c_int, c_int, c_char_p , c_int] _lib.TCOD_text_set_colors.restype=c_void _lib.TCOD_text_set_colors.argtypes=[c_void_p , c_int , c_int , c_float] _lib.TCOD_text_update.restype=c_bool _lib.TCOD_text_update.argtypes=[c_void_p , c_int ] _lib.TCOD_text_render.restype=c_void _lib.TCOD_text_render.argtypes=[c_void_p , c_void_p ] _lib.TCOD_text_get.restype=c_char_p _lib.TCOD_text_get.argtypes=[c_void_p ] _lib.TCOD_text_reset.restype=c_void _lib.TCOD_text_reset.argtypes=[c_void_p ] _lib.TCOD_text_delete.restype=c_void _lib.TCOD_text_delete.argtypes=[c_void_p ] _lib.TCOD_zip_new.restype=c_void_p _lib.TCOD_zip_new.argtypes=[] _lib.TCOD_zip_delete.restype=c_void _lib.TCOD_zip_delete.argtypes=[c_void_p ] _lib.TCOD_zip_put_char.restype=c_void _lib.TCOD_zip_put_char.argtypes=[c_void_p , c_char ] _lib.TCOD_zip_put_int.restype=c_void _lib.TCOD_zip_put_int.argtypes=[c_void_p , c_int] _lib.TCOD_zip_put_float.restype=c_void _lib.TCOD_zip_put_float.argtypes=[c_void_p , c_float ] _lib.TCOD_zip_put_string.restype=c_void _lib.TCOD_zip_put_string.argtypes=[c_void_p , c_char_p] _lib.TCOD_zip_put_color.restype=c_void _lib.TCOD_zip_put_color.argtypes=[c_void_p , c_int ] _lib.TCOD_zip_put_image.restype=c_void _lib.TCOD_zip_put_image.argtypes=[c_void_p , c_void_p ] _lib.TCOD_zip_put_console.restype=c_void _lib.TCOD_zip_put_console.argtypes=[c_void_p , c_void_p ] _lib.TCOD_zip_put_data.restype=c_void _lib.TCOD_zip_put_data.argtypes=[c_void_p , c_int,c_void_p] _lib.TCOD_zip_get_current_bytes.restype=c_int _lib.TCOD_zip_get_current_bytes.argtypes=[c_void_p ] _lib.TCOD_zip_save_to_file.restype=c_int _lib.TCOD_zip_save_to_file.argtypes=[c_void_p , c_char_p] _lib.TCOD_zip_load_from_file.restype=c_int _lib.TCOD_zip_load_from_file.argtypes=[c_void_p , c_char_p] _lib.TCOD_zip_get_char.restype=c_char _lib.TCOD_zip_get_char.argtypes=[c_void_p ] _lib.TCOD_zip_get_int.restype=c_int _lib.TCOD_zip_get_int.argtypes=[c_void_p ] _lib.TCOD_zip_get_float.restype=c_float _lib.TCOD_zip_get_float.argtypes=[c_void_p ] _lib.TCOD_zip_get_string.restype=c_char_p _lib.TCOD_zip_get_string.argtypes=[c_void_p ] _lib.TCOD_zip_get_color.restype=c_int _lib.TCOD_zip_get_color.argtypes=[c_void_p ] _lib.TCOD_zip_get_image.restype=c_void_p _lib.TCOD_zip_get_image.argtypes=[c_void_p ] _lib.TCOD_zip_get_console.restype=c_void_p _lib.TCOD_zip_get_console.argtypes=[c_void_p ] _lib.TCOD_zip_get_data.restype=c_int _lib.TCOD_zip_get_data.argtypes=[c_void_p , c_int,c_void_p] _lib.TCOD_zip_get_remaining_bytes.restype=c_int _lib.TCOD_zip_get_remaining_bytes.argtypes=[c_void_p ] _lib.TCOD_zip_skip_bytes.restype=c_void _lib.TCOD_zip_skip_bytes.argtypes=[c_void_p ,c_int ] libtcod-1.6.4+dfsg/python/libtcodpy/cprotos.py000066400000000000000000000162631321276576200214610ustar00rootroot00000000000000 from ctypes import * from libtcodpy import Color c_void = None def setup_protos(lib): #_lib.TCOD_line.restype=c_bool #_lib.TCOD_line.argtypes=[c_int, c_int, c_int, c_int, TCOD_line_listener_t] #_lib.TCOD_line_mt.restype=c_bool #_lib.TCOD_line_mt.argtypes=[c_int, c_int, c_int, c_int, TCOD_line_listener_t , c_void_p] #_lib.c_void_pre_order.restype=c_bool #_lib.c_void_pre_order.argtypes=[c_void_p, TCOD_bsp_callback_t , void_p] #_lib.TCOD_bsp_traverse_in_order.restype=c_bool #_lib.TCOD_bsp_traverse_in_order.argtypes=[c_void_p, TCOD_bsp_callback_t , void_p] #_lib.c_void_post_order.restype=c_bool #_lib.c_void_post_order.argtypes=[c_void_p, TCOD_bsp_callback_t , void_p] #_lib.TCOD_bsp_traverse_level_order.restype=c_bool #_lib.TCOD_bsp_traverse_level_order.argtypes=[c_void_p, TCOD_bsp_callback_t , void_p] #_lib.TCOD_bsp_traverse_inverted_level_order.restype=c_bool #_lib.TCOD_bsp_traverse_inverted_level_order.argtypes=[c_void_p, TCOD_bsp_callback_t , void_p] lib.TCOD_color_RGB.restype=Color lib.TCOD_color_RGB.argtypes=[c_byte , c_byte , c_byte ] lib.TCOD_color_HSV.restype=Color lib.TCOD_color_HSV.argtypes=[c_float , c_float , c_float ] # lib.TCOD_color_lerp .restype=c_int # lib.TCOD_color_lerp .argtypes=[c_int , c_int , c_float ] lib.TCOD_color_get_hue .restype=c_float lib.TCOD_color_get_hue .argtypes=[Color ] lib.TCOD_color_set_hue .restype=c_void lib.TCOD_color_set_hue .argtypes=[POINTER(Color), c_float ] lib.TCOD_color_get_saturation .restype=c_float lib.TCOD_color_get_saturation .argtypes=[Color ] lib.TCOD_color_set_saturation .restype=c_void lib.TCOD_color_set_saturation .argtypes=[POINTER(Color), c_float ] lib.TCOD_color_get_value .restype=c_float lib.TCOD_color_get_value .argtypes=[Color ] lib.TCOD_color_set_value .restype=c_void lib.TCOD_color_set_value .argtypes=[POINTER(Color), c_float ] lib.TCOD_color_shift_hue .restype=c_void lib.TCOD_color_shift_hue .argtypes=[POINTER(Color), c_float ] # lib.TCOD_console_print.restype=c_void # lib.TCOD_console_print.argtypes=[c_void_p ,c_int, c_int, c_char_p, ...] # lib.TCOD_console_print_ex.restype=c_void # lib.TCOD_console_print_ex.argtypes=[c_void_p ,c_int, c_int, c_int , c_int , c_char_p, ...] # lib.TCOD_console_print_rect.restype=c_int # lib.TCOD_console_print_rect.argtypes=[c_void_p ,c_int, c_int, c_int, c_int, c_char_p, ...] # lib.TCOD_console_print_rect_ex.restype=c_int # lib.TCOD_console_print_rect_ex.argtypes=[c_void_p ,c_int, c_int, c_int, c_int, c_int , c_int , c_char_p, ...] # lib.TCOD_console_get_height_rect.restype=c_int # lib.TCOD_console_get_height_rect.argtypes=[c_void_p ,c_int, c_int, c_int, c_int, c_char_p, ...] # lib.TCOD_console_print_frame.restype=c_void # lib.TCOD_console_print_frame.argtypes=[c_void_p ,c_int,c_int,c_int,c_int, c_bool , c_int , c_char_p, ...] # lib.TCOD_console_print_utf.restype=c_void # lib.TCOD_console_print_utf.argtypes=[c_void_p ,c_int, c_int, wchar_t_p, ...] # lib.TCOD_console_print_ex_utf.restype=c_void # lib.TCOD_console_print_ex_utf.argtypes=[c_void_p ,c_int, c_int, c_int , c_int , wchar_t_p, ...] # lib.TCOD_console_print_rect_utf.restype=c_int # lib.TCOD_console_print_rect_utf.argtypes=[c_void_p ,c_int, c_int, c_int, c_int, wchar_t_p, ...] # lib.TCOD_console_print_rect_ex_utf.restype=c_int # lib.TCOD_console_print_rect_ex_utf.argtypes=[c_void_p ,c_int, c_int, c_int, c_int, c_int , c_int , wchar_t_p, ...] # lib.TCOD_console_check_for_keypress.restype=TCOD_key_t # lib.TCOD_console_check_for_keypress.argtypes=[c_int] # lib.TCOD_console_wait_for_keypress.restype=TCOD_key_t # lib.TCOD_console_wait_for_keypress.argtypes=[c_bool ] # lib.TCOD_random_dice_new .restype=TCOD_dice_t # lib.TCOD_random_dice_new .argtypes=[c_char_p ] # lib.TCOD_random_dice_roll .restype=c_int # lib.TCOD_random_dice_roll .argtypes=[c_void_p , TCOD_dice_t ] # lib.TCOD_mouse_get_status.restype=TCOD_mouse_t # lib.TCOD_mouse_get_status.argtypes=[] # lib.TCOD_parser_new_custom_type.restype=c_int # lib.TCOD_parser_new_custom_type.argtypes=[c_void_p ,TCOD_parser_custom_t custom_type_] lib.TCOD_parser_error.restype=c_void # lib.TCOD_parser_error.argtypes=[c_char_p, ...] # lib.TCOD_parser_property.restype=TCOD_dice_t # lib.TCOD_parser_property.argtypes=[c_void_p , c_char_p] # lib.TCOD_parser_py.restype=c_void # lib.TCOD_parser_py.argtypes=[c_void_p , c_char_p, c_void_p] # lib.TCOD_parse_c_bool_value.restype=TCOD_value_t # lib.TCOD_parse_c_bool_value.argtypes=[] # lib.TCOD_parse_char_value.restype=TCOD_value_t # lib.TCOD_parse_char_value.argtypes=[] # lib.TCOD_parse_integer_value.restype=TCOD_value_t # lib.TCOD_parse_integer_value.argtypes=[] # lib.TCOD_parse_float_value.restype=TCOD_value_t # lib.TCOD_parse_float_value.argtypes=[] # lib.TCOD_parse_string_value.restype=TCOD_value_t # lib.TCOD_parse_string_value.argtypes=[] # lib.TCOD_parse_color_value.restype=TCOD_value_t # lib.TCOD_parse_color_value.argtypes=[] # lib.TCOD_parse_dice_value.restype=TCOD_value_t # lib.TCOD_parse_dice_value.argtypes=[] # lib.TCOD_parse_value_list_value.restype=TCOD_value_t # lib.TCOD_parse_value_list_value.argtypes=[c_void_p,c_int] # lib.TCOD_parse_property_value.restype=TCOD_value_t # lib.TCOD_parse_property_value.argtypes=[c_void_p, c_void_p , c_char_p, c_bool ] # lib.TCOD_path_new_using_function.restype=c_void_p # lib.TCOD_path_new_using_function.argtypes=[c_int, c_int, TCOD_path_func_t ,c_void_p, c_float ] # lib.TCOD_dijkstra_new_using_function.restype=c_void_p # lib.TCOD_dijkstra_new_using_function.argtypes=[c_int, c_int, TCOD_path_func_t ,c_void_p, c_float ] lib.TCOD_sys_clipboard_set.restype=c_void lib.TCOD_sys_clipboard_set.argtypes=[c_char_p] lib.TCOD_sys_clipboard_get.restype=c_char_p lib.TCOD_sys_clipboard_get.argtypes=[] #_lib.TCOD_thread_new.restype=TCOD_thread_t #_lib.TCOD_thread_new.argtypes=[c_int(*func)(void_p),c_void_p] #_lib.TCOD_thread_delete.restype=c_void #_lib.TCOD_thread_delete.argtypes=[TCOD_thread_t ] #_lib.TCOD_load_library.restype=TCOD_library_t #_lib.TCOD_load_library.argtypes=[c_char_p] #_lib.TCOD_get_function_address.restype=c_void_p #_lib.TCOD_get_function_address.argtypes=[TCOD_library_t , c_char_pfunction_] #_lib.TCOD_close_library.restype=c_void #_lib.TCOD_close_library.argtypes=[TCOD_library_] #_lib.TCOD_sys_register_SDL_renderer.restype=c_void #_lib.TCOD_sys_register_SDL_renderer.argtypes=[SDL_renderer_t ] lib.TCOD_console_double_hline.restype=c_void lib.TCOD_console_double_hline.argtypes=[c_void_p ,c_int,c_int, c_int] lib.TCOD_console_double_vline.restype=c_void lib.TCOD_console_double_vline.argtypes=[c_void_p ,c_int,c_int] lib.TCOD_console_print_double_frame.restype=c_void lib.TCOD_console_print_double_frame.argtypes=[c_void_p ,c_int,c_int] lib.TCOD_console_print_return_string.restype=c_char_p lib.TCOD_console_print_return_string.argtypes=[c_void_p ,c_int] lib.TCOD_image_set_key_color_wrapper.restype=c_void lib.TCOD_image_set_key_color_wrapper.argtypes=[c_void_p ] libtcod-1.6.4+dfsg/python/python.pyproj000066400000000000000000000035721321276576200202120ustar00rootroot00000000000000 Debug 2.0 {9f5a5967-268c-4d0d-a182-4112a94abe4b} tests\test_libtcodpy.py . . {888888a0-9f3d-457c-b088-3a5042f75d52} Standard Python launcher Global|PythonCore|2.7 True LIBTCOD_DLL_PATH=$(SolutionDir)..\dependencies\x64\$(Configuration);$(SolutionDir)\libtcod\x64\$(Configuration) False 10.0 libtcod-1.6.4+dfsg/python/samples_py.py000066400000000000000000002167711321276576200201610ustar00rootroot00000000000000#!/usr/bin/python # # libtcod Python samples # This code demonstrates various usages of libtcod modules # It's in the public domain. # from __future__ import print_function import math import os import libtcodpy as libtcod xrange = range # Import Psyco if available try: import psyco psyco.full() except ImportError: pass SAMPLE_SCREEN_WIDTH = 46 SAMPLE_SCREEN_HEIGHT = 20 SAMPLE_SCREEN_X = 20 SAMPLE_SCREEN_Y = 10 cwd_path = os.path.dirname(os.path.realpath(__file__)) data_path = os.path.abspath(os.path.join(cwd_path, '..', 'data')) font = os.path.join(data_path, 'fonts', 'consolas10x10_gs_tc.png') libtcod.console_set_custom_font(font, libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(80, 50, 'libtcod Python sample', False) sample_console = libtcod.console_new(SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT) ############################################# # parser unit test ############################################# # parser declaration if True: print ('***** File Parser test *****') parser=libtcod.parser_new() struct=libtcod.parser_new_struct(parser,'myStruct') libtcod.struct_add_property(struct,'bool_field', libtcod.TYPE_BOOL, True) libtcod.struct_add_property(struct,'char_field', libtcod.TYPE_CHAR, True) libtcod.struct_add_property(struct,'int_field', libtcod.TYPE_INT, True) libtcod.struct_add_property(struct,'float_field', libtcod.TYPE_FLOAT, True) libtcod.struct_add_property(struct,'color_field', libtcod.TYPE_COLOR, True) libtcod.struct_add_property(struct,'dice_field', libtcod.TYPE_DICE, True) libtcod.struct_add_property(struct,'string_field', libtcod.TYPE_STRING, True) libtcod.struct_add_list_property(struct,'bool_list', libtcod.TYPE_BOOL, True) libtcod.struct_add_list_property(struct,'char_list', libtcod.TYPE_CHAR, True) libtcod.struct_add_list_property(struct,'integer_list', libtcod.TYPE_INT, True) libtcod.struct_add_list_property(struct,'float_list', libtcod.TYPE_FLOAT, True) libtcod.struct_add_list_property(struct,'string_list', libtcod.TYPE_STRING, True) libtcod.struct_add_list_property(struct,'color_list', libtcod.TYPE_COLOR, True) ## # dice lists doesn't work yet ## libtcod.struct_add_list_property(struct,'dice_list', libtcod.TYPE_DICE, ## True) # default listener print ('***** Default listener *****') libtcod.parser_run(parser, os.path.join(data_path,'cfg','sample.cfg')) print ('bool_field : ', \ libtcod.parser_get_bool_property(parser,'myStruct.bool_field')) print ('char_field : ', \ libtcod.parser_get_char_property(parser,'myStruct.char_field')) print ('int_field : ', \ libtcod.parser_get_int_property(parser,'myStruct.int_field')) print ('float_field : ', \ libtcod.parser_get_float_property(parser,'myStruct.float_field')) print ('color_field : ', \ libtcod.parser_get_color_property(parser,'myStruct.color_field')) print ('dice_field : ', \ libtcod.parser_get_dice_property(parser,'myStruct.dice_field')) print ('string_field : ', \ libtcod.parser_get_string_property(parser,'myStruct.string_field')) print ('bool_list : ', \ libtcod.parser_get_list_property(parser,'myStruct.bool_list', libtcod.TYPE_BOOL)) print ('char_list : ', \ libtcod.parser_get_list_property(parser,'myStruct.char_list', libtcod.TYPE_CHAR)) print ('integer_list : ', \ libtcod.parser_get_list_property(parser,'myStruct.integer_list', libtcod.TYPE_INT)) print ('float_list : ', \ libtcod.parser_get_list_property(parser,'myStruct.float_list', libtcod.TYPE_FLOAT)) print ('string_list : ', \ libtcod.parser_get_list_property(parser,'myStruct.string_list', libtcod.TYPE_STRING)) print ('color_list : ', \ libtcod.parser_get_list_property(parser,'myStruct.color_list', libtcod.TYPE_COLOR)) ## print ('dice_list : ', \ ## libtcod.parser_get_list_property(parser,'myStruct.dice_list', ## libtcod.TYPE_DICE)) # custom listener print ('***** Custom listener *****') class MyListener: def new_struct(self, struct, name): print ('new structure type', libtcod.struct_get_name(struct), \ ' named ', name ) return True def new_flag(self, name): print ('new flag named ', name) return True def new_property(self,name, typ, value): type_names = ['NONE', 'BOOL', 'CHAR', 'INT', 'FLOAT', 'STRING', \ 'COLOR', 'DICE'] type_name = type_names[typ & 0xff] if typ & libtcod.TYPE_LIST: type_name = 'LIST<%s>' % type_name print ('new property named ', name,' type ',type_name, \ ' value ', value) return True def end_struct(self, struct, name): print ('end structure type', libtcod.struct_get_name(struct), \ ' named ', name) return True def error(self,msg): print ('error : ', msg) return True libtcod.parser_run(parser, os.path.join(data_path,'cfg','sample.cfg'), MyListener()) ############################################# # end of parser unit test ############################################# ############################################# # true color sample ############################################# tc_cols = [libtcod.Color(50, 40, 150), libtcod.Color(240, 85, 5), libtcod.Color(50, 35, 240), libtcod.Color(10, 200, 130), ] tc_dirr = [1, -1, 1, 1] tc_dirg = [1, -1, -1, 1] tc_dirb = [1, 1, 1, -1] def render_colors(first, key, mouse): global tc_cols, tc_dirr, tc_dirg, tc_dirb, tc_fast TOPLEFT = 0 TOPRIGHT = 1 BOTTOMLEFT = 2 BOTTOMRIGHT = 3 if first: libtcod.sys_set_fps(0) libtcod.console_clear(sample_console) tc_fast = False for c in range(4): # move each corner color component=libtcod.random_get_int(None, 0, 2) if component == 0: tc_cols[c].r += 5 * tc_dirr[c] if tc_cols[c].r == 255: tc_dirr[c] = -1 elif tc_cols[c].r == 0: tc_dirr[c] = 1 elif component == 1: tc_cols[c].g += 5 * tc_dirg[c] if tc_cols[c].g == 255: tc_dirg[c] = -1 elif tc_cols[c].g == 0: tc_dirg[c] = 1 elif component == 2: tc_cols[c].b += 5 * tc_dirb[c] if tc_cols[c].b == 255: tc_dirb[c] = -1 elif tc_cols[c].b == 0: tc_dirb[c] = 1 if not tc_fast: # interpolate corner colors for x in range(SAMPLE_SCREEN_WIDTH): xcoef = float(x) / (SAMPLE_SCREEN_WIDTH - 1) top = libtcod.color_lerp(tc_cols[TOPLEFT], tc_cols[TOPRIGHT], xcoef) bottom = libtcod.color_lerp(tc_cols[BOTTOMLEFT], tc_cols[BOTTOMRIGHT], xcoef) for y in range(SAMPLE_SCREEN_HEIGHT): ycoef = float(y) / (SAMPLE_SCREEN_HEIGHT - 1) curColor = libtcod.color_lerp(top, bottom, ycoef) libtcod.console_set_char_background(sample_console, x, y, curColor, libtcod.BKGND_SET) textColor = libtcod.console_get_char_background(sample_console, SAMPLE_SCREEN_WIDTH // 2, 5) textColor.r = 255 - textColor.r textColor.g = 255 - textColor.g textColor.b = 255 - textColor.b libtcod.console_set_default_foreground(sample_console, textColor) for x in range(SAMPLE_SCREEN_WIDTH): for y in range(SAMPLE_SCREEN_HEIGHT): col = libtcod.console_get_char_background(sample_console, x, y) col = libtcod.color_lerp(col, libtcod.black, 0.5) c = libtcod.random_get_int(None, ord('a'), ord('z')) libtcod.console_set_default_foreground(sample_console, col) libtcod.console_put_char(sample_console, x, y, c, libtcod.BKGND_NONE) else: # same, but using the ConsoleBuffer class to speed up rendering buffer = libtcod.ConsoleBuffer(SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT) # initialize buffer c = libtcod.random_get_int(None, ord('a'), ord('z')) for x in xrange(SAMPLE_SCREEN_WIDTH): xcoef = float(x) / (SAMPLE_SCREEN_WIDTH - 1) top = libtcod.color_lerp(tc_cols[TOPLEFT], tc_cols[TOPRIGHT], xcoef) bottom = libtcod.color_lerp(tc_cols[BOTTOMLEFT], tc_cols[BOTTOMRIGHT], xcoef) for y in xrange(SAMPLE_SCREEN_HEIGHT): # for maximum speed, we avoid using any libtcod function in # this inner loop, except for the ConsoleBuffer's functions. ycoef = float(y) / (SAMPLE_SCREEN_HEIGHT - 1) r = int(top.r * ycoef + bottom.r * (1 - ycoef)) g = int(top.g * ycoef + bottom.g * (1 - ycoef)) b = int(top.b * ycoef + bottom.b * (1 - ycoef)) c += 1 if c > ord('z'): c = ord('a') # set background, foreground and char with a single function buffer.set(x, y, r, g, b, r / 2, g / 2, b / 2, chr(c)) buffer.blit(sample_console) # update console with the buffer's contents libtcod.console_set_default_foreground(sample_console, libtcod.Color(int(r), int(g), int(b))) libtcod.console_set_default_background(sample_console, libtcod.grey) libtcod.console_print_rect_ex(sample_console, SAMPLE_SCREEN_WIDTH // 2, 5, SAMPLE_SCREEN_WIDTH - 2, SAMPLE_SCREEN_HEIGHT - 1, libtcod.BKGND_MULTIPLY, libtcod.CENTER, "The Doryen library uses 24 bits " "colors, for both background and " "foreground.") if key.c == ord('f'): tc_fast = not tc_fast libtcod.console_set_default_foreground(sample_console, libtcod.white) libtcod.console_print(sample_console, 1, SAMPLE_SCREEN_HEIGHT - 2, "F : turn fast rendering (Python 2.6 only) %s" % ("off" if tc_fast else "on")) ############################################# # offscreen console sample ############################################# oc_secondary = None oc_screenshot = None oc_counter = 0 oc_x = 0 oc_y = 0 oc_init = False oc_xdir = 1 oc_ydir = 1 def render_offscreen(first, key, mouse): global oc_secondary, oc_screenshot global oc_counter, oc_x, oc_y, oc_init, oc_xdir, oc_ydir if not oc_init: oc_init = True oc_secondary = libtcod.console_new(SAMPLE_SCREEN_WIDTH // 2, SAMPLE_SCREEN_HEIGHT // 2) oc_screenshot = libtcod.console_new(SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT) libtcod.console_print_frame(oc_secondary, 0, 0, SAMPLE_SCREEN_WIDTH // 2, SAMPLE_SCREEN_HEIGHT // 2, False, libtcod.BKGND_NONE, 'Offscreen console') libtcod.console_print_rect_ex(oc_secondary, SAMPLE_SCREEN_WIDTH // 4, 2, SAMPLE_SCREEN_WIDTH // 2 - 2, SAMPLE_SCREEN_HEIGHT // 2, libtcod.BKGND_NONE, libtcod.CENTER, b"You can render to an offscreen " b"console and blit in on another " b"one, simulating alpha " b"transparency.") if first: libtcod.sys_set_fps(30) # get a "screenshot" of the current sample screen libtcod.console_blit(sample_console, 0, 0, SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT, oc_screenshot, 0, 0) oc_counter += 1 if oc_counter % 20 == 0: oc_x += oc_xdir oc_y += oc_ydir if oc_x == SAMPLE_SCREEN_WIDTH / 2 + 5: oc_xdir = -1 elif oc_x == -5: oc_xdir = 1 if oc_y == SAMPLE_SCREEN_HEIGHT / 2 + 5: oc_ydir = -1 elif oc_y == -5: oc_ydir = 1 libtcod.console_blit(oc_screenshot, 0, 0, SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT, sample_console, 0, 0) libtcod.console_blit(oc_secondary, 0, 0, SAMPLE_SCREEN_WIDTH // 2, SAMPLE_SCREEN_HEIGHT // 2, sample_console, oc_x, oc_y, 1.0,0.75) ############################################# # line drawing sample ############################################# line_bk = libtcod.Color() line_init = False line_bk_flag = libtcod.BKGND_SET def render_lines(first, key, mouse): global line_bk, line_init, line_bk_flag flag_names=['BKGND_NONE', 'BKGND_SET', 'BKGND_MULTIPLY', 'BKGND_LIGHTEN', 'BKGND_DARKEN', 'BKGND_SCREEN', 'BKGND_COLOR_DODGE', 'BKGND_COLOR_BURN', 'BKGND_ADD', 'BKGND_ADDALPHA', 'BKGND_BURN', 'BKGND_OVERLAY', 'BKGND_ALPHA', ] if key.vk in (libtcod.KEY_ENTER, libtcod.KEY_KPENTER): line_bk_flag += 1 if (line_bk_flag & 0xff) > libtcod.BKGND_ALPH: line_bk_flag=libtcod.BKGND_NONE alpha = 0.0 if (line_bk_flag & 0xff) == libtcod.BKGND_ALPH: # for the alpha mode, update alpha every frame alpha = (1.0 + math.cos(libtcod.sys_elapsed_seconds() * 2)) / 2.0 line_bk_flag = libtcod.BKGND_ALPHA(alpha) elif (line_bk_flag & 0xff) == libtcod.BKGND_ADDA: # for the add alpha mode, update alpha every frame alpha = (1.0 + math.cos(libtcod.sys_elapsed_seconds() * 2)) / 2.0 line_bk_flag = libtcod.BKGND_ADDALPHA(alpha) if not line_init: line_bk = libtcod.console_new(SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT) # initialize the colored background for x in range(SAMPLE_SCREEN_WIDTH): for y in range(SAMPLE_SCREEN_HEIGHT): col = libtcod.Color(x * 255 // (SAMPLE_SCREEN_WIDTH - 1), (x + y) * 255 // (SAMPLE_SCREEN_WIDTH - 1 + SAMPLE_SCREEN_HEIGHT - 1), y * 255 // (SAMPLE_SCREEN_HEIGHT-1)) libtcod.console_set_char_background(line_bk, x, y, col, libtcod.BKGND_SET) line_init = True if first: libtcod.sys_set_fps(30) libtcod.console_set_default_foreground(sample_console, libtcod.white) libtcod.console_blit(line_bk, 0, 0, SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT, sample_console, 0, 0) recty = int((SAMPLE_SCREEN_HEIGHT - 2) * ((1.0 + math.cos(libtcod.sys_elapsed_seconds())) / 2.0)) for x in range(SAMPLE_SCREEN_WIDTH): col = libtcod.Color(x * 255 // SAMPLE_SCREEN_WIDTH, x * 255 // SAMPLE_SCREEN_WIDTH, x * 255 // SAMPLE_SCREEN_WIDTH) libtcod.console_set_char_background(sample_console, x, recty, col, line_bk_flag) libtcod.console_set_char_background(sample_console, x, recty + 1, col, line_bk_flag) libtcod.console_set_char_background(sample_console, x, recty + 2, col, line_bk_flag) angle = libtcod.sys_elapsed_seconds() * 2.0 cos_angle=math.cos(angle) sin_angle=math.sin(angle) xo = int(SAMPLE_SCREEN_WIDTH // 2 * (1 + cos_angle)) yo = int(SAMPLE_SCREEN_HEIGHT // 2 + sin_angle * SAMPLE_SCREEN_WIDTH // 2) xd = int(SAMPLE_SCREEN_WIDTH // 2 * (1 - cos_angle)) yd = int(SAMPLE_SCREEN_HEIGHT // 2 - sin_angle * SAMPLE_SCREEN_WIDTH // 2) # draw the line # in Python the easiest way is to use the line iterator for x,y in libtcod.line_iter(xo, yo, xd, yd): if 0 <= x < SAMPLE_SCREEN_WIDTH and \ 0 <= y < SAMPLE_SCREEN_HEIGHT: libtcod.console_set_char_background(sample_console, x, y, libtcod.light_blue, line_bk_flag) libtcod.console_print(sample_console, 2, 2, '%s (ENTER to change)' % flag_names[line_bk_flag & 0xff]) ############################################# # noise sample ############################################# noise_func = 0 noise_dx = 0.0 noise_dy = 0.0 noise_octaves = 4.0 noise_zoom = 3.0 noise_hurst = libtcod.NOISE_DEFAULT_HURST noise_lacunarity = libtcod.NOISE_DEFAULT_LACUNARITY noise = libtcod.noise_new(2) noise_img=libtcod.image_new(SAMPLE_SCREEN_WIDTH*2,SAMPLE_SCREEN_HEIGHT*2) def render_noise(first, key, mouse): global noise_func, noise_img global noise_dx, noise_dy global noise_octaves, noise_zoom, noise_hurst, noise_lacunarity, noise PERLIN = 0 SIMPLEX = 1 WAVELET = 2 FBM_PERLIN = 3 TURBULENCE_PERLIN = 4 FBM_SIMPLEX = 5 TURBULENCE_SIMPLEX = 6 FBM_WAVELET = 7 TURBULENCE_WAVELET = 8 funcName=[ '1 : perlin noise ', '2 : simplex noise ', '3 : wavelet noise ', '4 : perlin fbm ', '5 : perlin turbulence ', '6 : simplex fbm ', '7 : simplex turbulence ', '8 : wavelet fbm ', '9 : wavelet turbulence ', ] if first: libtcod.sys_set_fps(30) libtcod.console_clear(sample_console) noise_dx += 0.01 noise_dy += 0.01 for y in range(2*SAMPLE_SCREEN_HEIGHT): for x in range(2*SAMPLE_SCREEN_WIDTH): f = [noise_zoom * x / (2*SAMPLE_SCREEN_WIDTH) + noise_dx, noise_zoom * y / (2*SAMPLE_SCREEN_HEIGHT) + noise_dy] value = 0.0 if noise_func == PERLIN: value = libtcod.noise_get(noise, f, libtcod.NOISE_PERLIN) elif noise_func == SIMPLEX: value = libtcod.noise_get(noise, f, libtcod.NOISE_SIMPLEX) elif noise_func == WAVELET: value = libtcod.noise_get(noise, f, libtcod.NOISE_WAVELET) elif noise_func == FBM_PERLIN: value = libtcod.noise_get_fbm(noise, f, noise_octaves, libtcod.NOISE_PERLIN) elif noise_func == TURBULENCE_PERLIN: value = libtcod.noise_get_turbulence(noise, f, noise_octaves, libtcod.NOISE_PERLIN) elif noise_func == FBM_SIMPLEX: value = libtcod.noise_get_fbm(noise, f, noise_octaves, libtcod.NOISE_SIMPLEX) elif noise_func == TURBULENCE_SIMPLEX: value = libtcod.noise_get_turbulence(noise, f, noise_octaves, libtcod.NOISE_SIMPLEX) elif noise_func == FBM_WAVELET: value = libtcod.noise_get_fbm(noise, f, noise_octaves, libtcod.NOISE_WAVELET) elif noise_func == TURBULENCE_WAVELET: value = libtcod.noise_get_turbulence(noise, f, noise_octaves, libtcod.NOISE_WAVELET) c = int((value + 1.0) / 2.0 * 255) if c < 0: c = 0 elif c > 255: c = 255 col = libtcod.Color(c // 2, c // 2, c) libtcod.image_put_pixel(noise_img,x,y,col) libtcod.console_set_default_background(sample_console, libtcod.grey) rectw = 24 recth = 13 if noise_func <= WAVELET: recth = 10 libtcod.image_blit_2x(noise_img,sample_console,0,0) libtcod.console_rect(sample_console, 2, 2, rectw, recth, False, libtcod.BKGND_MULTIPLY) for y in range(2,2+recth): for x in range(2,2+rectw): col=libtcod.console_get_char_foreground(sample_console,x,y) col = col * libtcod.grey libtcod.console_set_char_foreground(sample_console,x,y,col) for curfunc in range(TURBULENCE_WAVELET + 1): if curfunc == noise_func: libtcod.console_set_default_foreground(sample_console, libtcod.white) libtcod.console_set_default_background(sample_console, libtcod.light_blue) libtcod.console_print_ex(sample_console, 2, 2 + curfunc, libtcod.BKGND_SET, libtcod.LEFT, funcName[curfunc]) else: libtcod.console_set_default_foreground(sample_console, libtcod.grey) libtcod.console_print(sample_console, 2, 2 + curfunc, funcName[curfunc]) libtcod.console_set_default_foreground(sample_console, libtcod.white) libtcod.console_print(sample_console, 2, 11, 'Y/H : zoom (%2.1f)' % noise_zoom) if noise_func > WAVELET: libtcod.console_print(sample_console, 2, 12, 'E/D : hurst (%2.1f)' % noise_hurst) libtcod.console_print(sample_console, 2, 13, 'R/F : lacunarity (%2.1f)' % noise_lacunarity) libtcod.console_print(sample_console, 2, 14, 'T/G : octaves (%2.1f)' % noise_octaves) if key.vk == libtcod.KEY_NONE: return if ord('9') >= key.c >= ord('1'): noise_func = key.c - ord('1') elif key.c in (ord('E'), ord('e')): noise_hurst += 0.1 libtcod.noise_delete(noise) noise = libtcod.noise_new(2,noise_hurst,noise_lacunarity) elif key.c in (ord('D'), ord('d')): noise_hurst -= 0.1 libtcod.noise_delete(noise) noise = libtcod.noise_new(2, noise_hurst, noise_lacunarity) elif key.c in (ord('R'), ord('r')): noise_lacunarity += 0.5 libtcod.noise_delete(noise) noise = libtcod.noise_new(2, noise_hurst, noise_lacunarity) elif key.c in (ord('F'), ord('f')): noise_lacunarity -= 0.5 libtcod.noise_delete(noise) noise = libtcod.noise_new(2, noise_hurst, noise_lacunarity) elif key.c in (ord('T'), ord('t')): noise_octaves += 0.5 elif key.c in (ord('G'), ord('g')): noise_octaves -= 0.5 elif key.c in (ord('Y'), ord('y')): noise_zoom += 0.2 elif key.c in (ord('H'), ord('h')): noise_zoom -= 0.2 ############################################# # field of view sample ############################################# fov_px = 20 fov_py = 10 fov_recompute = True fov_torch = False fov_map = None fov_dark_wall = libtcod.Color(0, 0, 100) fov_light_wall = libtcod.Color(130, 110, 50) fov_dark_ground = libtcod.Color(50, 50, 150) fov_light_ground = libtcod.Color(200, 180, 50) fov_noise = None fov_torchx = 0.0 fov_init = False fov_light_walls = True fov_algo_num = 0 fov_algo_names = ['BASIC ','DIAMOND ', 'SHADOW ', 'PERMISSIVE0','PERMISSIVE1','PERMISSIVE2','PERMISSIVE3','PERMISSIVE4', 'PERMISSIVE5','PERMISSIVE6','PERMISSIVE7','PERMISSIVE8','RESTRICTIVE'] def render_fov(first, key, mouse): global fov_px, fov_py, fov_map, fov_dark_wall, fov_light_wall global fov_dark_ground, fov_light_ground global fov_recompute, fov_torch, fov_noise, fov_torchx, fov_init global fov_light_walls, fov_algo_num, fov_algo_names smap = ['##############################################', '####################### #################', '##################### # ###############', '###################### ### ###########', '################## ##### ####', '################ ######## ###### ####', '############### #################### ####', '################ ###### ##', '######## ####### ###### # # # ##', '######## ###### ### ##', '######## ##', '#### ###### ### # # # ##', '#### ### ########## #### ##', '#### ### ########## ###########=##########', '#### ################## ##### #####', '#### ### #### ##### #####', '#### # #### #####', '######## # #### ##### #####', '######## ##### ####################', '##############################################', ] TORCH_RADIUS = 10 SQUARED_TORCH_RADIUS = TORCH_RADIUS * TORCH_RADIUS dx = 0.0 dy = 0.0 di = 0.0 if not fov_init: fov_init = True fov_map = libtcod.map_new(SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT) for y in range(SAMPLE_SCREEN_HEIGHT): for x in range(SAMPLE_SCREEN_WIDTH): if smap[y][x] == ' ': # ground libtcod.map_set_properties(fov_map, x, y, True, True) elif smap[y][x] == '=': # window libtcod.map_set_properties(fov_map, x, y, True, False) # 1d noise for the torch flickering fov_noise = libtcod.noise_new(1, 1.0, 1.0) torchs = 'off' lights = 'off' if fov_torch: torchs = 'on ' if fov_light_walls : lights='on ' if first: libtcod.sys_set_fps(30) # we draw the foreground only the first time. # during the player movement, only the @ is redrawn. # the rest impacts only the background color # draw the help text & player @ libtcod.console_clear(sample_console) libtcod.console_set_default_foreground(sample_console, libtcod.white) libtcod.console_print(sample_console, 1, 1, "IJKL : move around\nT : torch fx %s\nW : light walls %s\n+-: algo %s" % (torchs,lights,fov_algo_names[fov_algo_num])) libtcod.console_set_default_foreground(sample_console, libtcod.black) libtcod.console_put_char(sample_console, fov_px, fov_py, '@', libtcod.BKGND_NONE) # draw windows for y in range(SAMPLE_SCREEN_HEIGHT): for x in range(SAMPLE_SCREEN_WIDTH): if smap[y][x] == '=': libtcod.console_put_char(sample_console, x, y, libtcod.CHAR_DHLINE, libtcod.BKGND_NONE) if fov_recompute: fov_recompute = False if fov_torch: libtcod.map_compute_fov(fov_map, fov_px, fov_py, TORCH_RADIUS, fov_light_walls, fov_algo_num) else: libtcod.map_compute_fov(fov_map, fov_px, fov_py, 0, fov_light_walls, fov_algo_num) if fov_torch: # slightly change the perlin noise parameter fov_torchx += 0.2 # randomize the light position between -1.5 and 1.5 tdx = [fov_torchx + 20.0] dx = libtcod.noise_get(noise, tdx, libtcod.NOISE_SIMPLEX) * 1.5 tdx[0] += 30.0 dy = libtcod.noise_get(noise, tdx, libtcod.NOISE_SIMPLEX) * 1.5 di = 0.2 * libtcod.noise_get(noise, [fov_torchx], libtcod.NOISE_SIMPLEX) for y in range(SAMPLE_SCREEN_HEIGHT): for x in range(SAMPLE_SCREEN_WIDTH): visible = libtcod.map_is_in_fov(fov_map, x, y) wall = (smap[y][x] == '#') if not visible: if wall: libtcod.console_set_char_background(sample_console, x, y, fov_dark_wall, libtcod.BKGND_SET) else: libtcod.console_set_char_background(sample_console, x, y, fov_dark_ground, libtcod.BKGND_SET) else: if not fov_torch: if wall: libtcod.console_set_char_background(sample_console, x, y, fov_light_wall, libtcod.BKGND_SET ) else: libtcod.console_set_char_background(sample_console, x, y, fov_light_ground, libtcod.BKGND_SET ) else: if wall: base = fov_dark_wall light = fov_light_wall else: base = fov_dark_ground light = fov_light_ground # cell distance to torch (squared) r = float(x - fov_px + dx) * (x - fov_px + dx) + \ (y - fov_py + dy) * (y - fov_py + dy) if r < SQUARED_TORCH_RADIUS: l = (SQUARED_TORCH_RADIUS - r) / SQUARED_TORCH_RADIUS \ + di if l < 0.0: l = 0.0 elif l> 1.0: l = 1.0 base = libtcod.color_lerp(base, light, l) libtcod.console_set_char_background(sample_console, x, y, base, libtcod.BKGND_SET) if key.c in (ord('I'), ord('i')): if smap[fov_py-1][fov_px] == ' ': libtcod.console_put_char(sample_console, fov_px, fov_py, ' ', libtcod.BKGND_NONE) fov_py -= 1 libtcod.console_put_char(sample_console, fov_px, fov_py, '@', libtcod.BKGND_NONE) fov_recompute = True elif key.c in (ord('K'), ord('k')): if smap[fov_py+1][fov_px] == ' ': libtcod.console_put_char(sample_console, fov_px, fov_py, ' ', libtcod.BKGND_NONE) fov_py += 1 libtcod.console_put_char(sample_console, fov_px, fov_py, '@', libtcod.BKGND_NONE) fov_recompute = True elif key.c in (ord('J'), ord('j')): if smap[fov_py][fov_px-1] == ' ': libtcod.console_put_char(sample_console, fov_px, fov_py, ' ', libtcod.BKGND_NONE) fov_px -= 1 libtcod.console_put_char(sample_console, fov_px, fov_py, '@', libtcod.BKGND_NONE) fov_recompute = True elif key.c in (ord('L'), ord('l')): if smap[fov_py][fov_px+1] == ' ': libtcod.console_put_char(sample_console, fov_px, fov_py, ' ', libtcod.BKGND_NONE) fov_px += 1 libtcod.console_put_char(sample_console, fov_px, fov_py, '@', libtcod.BKGND_NONE) fov_recompute = True elif key.c in (ord('T'), ord('t')): fov_torch = not fov_torch libtcod.console_set_default_foreground(sample_console, libtcod.white) libtcod.console_print(sample_console, 1, 1, "IJKL : move around\nT : torch fx %s\nW : light walls %s\n+-: algo %s" % (torchs,lights,fov_algo_names[fov_algo_num])) libtcod.console_set_default_foreground(sample_console, libtcod.black) elif key.c in (ord('W'), ord('w')): fov_light_walls = not fov_light_walls libtcod.console_set_default_foreground(sample_console, libtcod.white) libtcod.console_print(sample_console, 1, 1, "IJKL : move around\nT : torch fx %s\nW : light walls %s\n+-: algo %s" % (torchs,lights,fov_algo_names[fov_algo_num])) libtcod.console_set_default_foreground(sample_console, libtcod.black) fov_recompute = True elif key.vk == libtcod.KEY_TEXT: if key.text in ("+", "-"): if key.text == b"+" and fov_algo_num < libtcod.NB_FOV_ALGORITHMS-1: fov_algo_num = fov_algo_num + 1 elif fov_algo_num > 0 : fov_algo_num = fov_algo_num - 1 libtcod.console_set_default_foreground(sample_console, libtcod.white) libtcod.console_print(sample_console, 1, 1, "IJKL : move around\nT : torch fx %s\nW : light walls %s\n+-: algo %s" % (torchs,lights,fov_algo_names[fov_algo_num])) libtcod.console_set_default_foreground(sample_console, libtcod.black) fov_recompute = True ############################################# # pathfinding sample ############################################# path_px = 20 path_py = 10 path_dx = 24 path_dy = 1 path_map = None path = None path_dijk_dist = 0.0 path_using_astar = True path_dijk = None path_recalculate = False path_busy = 0.0 path_oldchar = ' ' path_init = False def render_path(first, key, mouse): global path_px, path_py, path_dx, path_dy, path_map, path, path_busy global path_oldchar, path_init, path_recalculate global path_dijk_dist, path_using_astar, path_dijk smap = ['##############################################', '####################### #################', '##################### # ###############', '###################### ### ###########', '################## ##### ####', '################ ######## ###### ####', '############### #################### ####', '################ ###### ##', '######## ####### ###### # # # ##', '######## ###### ### ##', '######## ##', '#### ###### ### # # # ##', '#### ### ########## #### ##', '#### ### ########## ###########=##########', '#### ################## ##### #####', '#### ### #### ##### #####', '#### # #### #####', '######## # #### ##### #####', '######## ##### ####################', '##############################################', ] TORCH_RADIUS = 10.0 SQUARED_TORCH_RADIUS = TORCH_RADIUS * TORCH_RADIUS if not path_init: path_init = True path_map = libtcod.map_new(SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT) for y in range(SAMPLE_SCREEN_HEIGHT): for x in range(SAMPLE_SCREEN_WIDTH): if smap[y][x] == ' ': # ground libtcod.map_set_properties(path_map, x, y, True, True) elif smap[y][x] == '=': # window libtcod.map_set_properties(path_map, x, y, True, False) path = libtcod.path_new_using_map(path_map) path_dijk = libtcod.dijkstra_new(path_map) if first: libtcod.sys_set_fps(30) # we draw the foreground only the first time. # during the player movement, only the @ is redrawn. # the rest impacts only the background color # draw the help text & player @ libtcod.console_clear(sample_console) libtcod.console_set_default_foreground(sample_console, libtcod.white) libtcod.console_put_char(sample_console, path_dx, path_dy, '+', libtcod.BKGND_NONE) libtcod.console_put_char(sample_console, path_px, path_py, '@', libtcod.BKGND_NONE) libtcod.console_print(sample_console, 1, 1, "IJKL / mouse :\nmove destination\nTAB : A*/dijkstra") libtcod.console_print(sample_console, 1, 4, "Using : A*") # draw windows for y in range(SAMPLE_SCREEN_HEIGHT): for x in range(SAMPLE_SCREEN_WIDTH): if smap[y][x] == '=': libtcod.console_put_char(sample_console, x, y, libtcod.CHAR_DHLINE, libtcod.BKGND_NONE) path_recalculate = True if path_recalculate: if path_using_astar : libtcod.path_compute(path, path_px, path_py, path_dx, path_dy) else: path_dijk_dist = 0.0 # compute dijkstra grid (distance from px,py) libtcod.dijkstra_compute(path_dijk,path_px,path_py) # get the maximum distance (needed for rendering) for y in range(SAMPLE_SCREEN_HEIGHT): for x in range(SAMPLE_SCREEN_WIDTH): d=libtcod.dijkstra_get_distance(path_dijk,x,y) if d > path_dijk_dist: path_dijk_dist=d # compute path from px,py to dx,dy libtcod.dijkstra_path_set(path_dijk,path_dx,path_dy) path_recalculate = False path_busy = 0.2 # draw the dungeon for y in range(SAMPLE_SCREEN_HEIGHT): for x in range(SAMPLE_SCREEN_WIDTH): if smap[y][x] == '#': libtcod.console_set_char_background(sample_console, x, y, fov_dark_wall, libtcod.BKGND_SET) else: libtcod.console_set_char_background(sample_console, x, y, fov_dark_ground, libtcod.BKGND_SET) # draw the path if path_using_astar : for i in range(libtcod.path_size(path)): x,y = libtcod.path_get(path, i) libtcod.console_set_char_background(sample_console, x, y, fov_light_ground, libtcod.BKGND_SET) else: for y in range(SAMPLE_SCREEN_HEIGHT): for x in range(SAMPLE_SCREEN_WIDTH): if smap[y][x] != '#': libtcod.console_set_char_background(sample_console, x, y, libtcod.color_lerp(fov_light_ground,fov_dark_ground, 0.9 * libtcod.dijkstra_get_distance(path_dijk,x,y) / path_dijk_dist), libtcod.BKGND_SET) for i in range(libtcod.dijkstra_size(path_dijk)): x,y=libtcod.dijkstra_get(path_dijk,i) libtcod.console_set_char_background(sample_console,x,y,fov_light_ground, libtcod.BKGND_SET ) # move the creature path_busy -= libtcod.sys_get_last_frame_length() if path_busy <= 0.0: path_busy = 0.2 if path_using_astar : if not libtcod.path_is_empty(path): libtcod.console_put_char(sample_console, path_px, path_py, ' ', libtcod.BKGND_NONE) path_px, path_py = libtcod.path_walk(path, True) libtcod.console_put_char(sample_console, path_px, path_py, '@', libtcod.BKGND_NONE) else: if not libtcod.dijkstra_is_empty(path_dijk): libtcod.console_put_char(sample_console, path_px, path_py, ' ', libtcod.BKGND_NONE) path_px, path_py = libtcod.dijkstra_path_walk(path_dijk) libtcod.console_put_char(sample_console, path_px, path_py, '@', libtcod.BKGND_NONE) path_recalculate = True if key.c in (ord('I'), ord('i')) and path_dy > 0: # destination move north libtcod.console_put_char(sample_console, path_dx, path_dy, path_oldchar, libtcod.BKGND_NONE) path_dy -= 1 path_oldchar = libtcod.console_get_char(sample_console, path_dx, path_dy) libtcod.console_put_char(sample_console, path_dx, path_dy, '+', libtcod.BKGND_NONE) if smap[path_dy][path_dx] == ' ': path_recalculate = True elif key.c in (ord('K'), ord('k')) and path_dy < SAMPLE_SCREEN_HEIGHT - 1: # destination move south libtcod.console_put_char(sample_console, path_dx, path_dy, path_oldchar, libtcod.BKGND_NONE) path_dy += 1 path_oldchar = libtcod.console_get_char(sample_console, path_dx, path_dy) libtcod.console_put_char(sample_console, path_dx, path_dy, '+', libtcod.BKGND_NONE) if smap[path_dy][path_dx] == ' ': path_recalculate = True elif key.c in (ord('J'), ord('j')) and path_dx > 0: # destination move west libtcod.console_put_char(sample_console, path_dx, path_dy, path_oldchar, libtcod.BKGND_NONE) path_dx -= 1 path_oldchar = libtcod.console_get_char(sample_console, path_dx, path_dy) libtcod.console_put_char(sample_console, path_dx, path_dy, '+', libtcod.BKGND_NONE) if smap[path_dy][path_dx] == ' ': path_recalculate = True elif key.c in (ord('L'), ord('l')) and path_dx < SAMPLE_SCREEN_WIDTH - 1: # destination move east libtcod.console_put_char(sample_console, path_dx, path_dy, path_oldchar, libtcod.BKGND_NONE) path_dx += 1 path_oldchar = libtcod.console_get_char(sample_console, path_dx, path_dy) libtcod.console_put_char(sample_console, path_dx, path_dy, '+', libtcod.BKGND_NONE) if smap[path_dy][path_dx] == ' ': path_recalculate = True elif key.vk == libtcod.KEY_TAB: path_using_astar = not path_using_astar if path_using_astar : libtcod.console_print(sample_console, 1, 4, "Using : A* ") else: libtcod.console_print(sample_console, 1, 4, "Using : Dijkstra") path_recalculate=True mx = mouse.cx - SAMPLE_SCREEN_X my = mouse.cy - SAMPLE_SCREEN_Y if 0 <= mx < SAMPLE_SCREEN_WIDTH and 0 <= my < SAMPLE_SCREEN_HEIGHT and \ (path_dx != mx or path_dy != my): libtcod.console_put_char(sample_console, path_dx, path_dy, path_oldchar, libtcod.BKGND_NONE) path_dx = mx path_dy = my path_oldchar = libtcod.console_get_char(sample_console, path_dx, path_dy) libtcod.console_put_char(sample_console, path_dx, path_dy, '+', libtcod.BKGND_NONE) if smap[path_dy][path_dx] == ' ': path_recalculate = True ############################################# # bsp sample ############################################# bsp_depth = 8 bsp_min_room_size = 4 # a room fills a random part of the node or the maximum available space ? bsp_random_room = False # if true, there is always a wall on north & west side of a room bsp_room_walls = True bsp_map = None # draw a vertical line def vline(m, x, y1, y2): if y1 > y2: y1,y2 = y2,y1 for y in range(y1,y2+1): m[x][y] = True # draw a vertical line up until we reach an empty space def vline_up(m, x, y): while y >= 0 and not m[x][y]: m[x][y] = True y -= 1 # draw a vertical line down until we reach an empty space def vline_down(m, x, y): while y < SAMPLE_SCREEN_HEIGHT and not m[x][y]: m[x][y] = True y += 1 # draw a horizontal line def hline(m, x1, y, x2): if x1 > x2: x1,x2 = x2,x1 for x in range(x1,x2+1): m[x][y] = True # draw a horizontal line left until we reach an empty space def hline_left(m, x, y): while x >= 0 and not m[x][y]: m[x][y] = True x -= 1 # draw a horizontal line right until we reach an empty space def hline_right(m, x, y): while x < SAMPLE_SCREEN_WIDTH and not m[x][y]: m[x][y]=True x += 1 # the class building the dungeon from the bsp nodes def traverse_node(node, dat): global bsp_map if libtcod.bsp_is_leaf(node): # calculate the room size minx = node.x + 1 maxx = node.x + node.w - 1 miny = node.y + 1 maxy = node.y + node.h - 1 if not bsp_room_walls: if minx > 1: minx -= 1 if miny > 1: miny -=1 if maxx == SAMPLE_SCREEN_WIDTH - 1: maxx -= 1 if maxy == SAMPLE_SCREEN_HEIGHT - 1: maxy -= 1 if bsp_random_room: minx = libtcod.random_get_int(None, minx, maxx - bsp_min_room_size + 1) miny = libtcod.random_get_int(None, miny, maxy - bsp_min_room_size + 1) maxx = libtcod.random_get_int(None, minx + bsp_min_room_size - 1, maxx) maxy = libtcod.random_get_int(None, miny + bsp_min_room_size - 1, maxy) # resize the node to fit the room node.x = minx node.y = miny node.w = maxx-minx + 1 node.h = maxy-miny + 1 # dig the room for x in range(minx, maxx + 1): for y in range(miny, maxy + 1): bsp_map[x][y] = True else: # resize the node to fit its sons left = libtcod.bsp_left(node) right = libtcod.bsp_right(node) node.x = min(left.x, right.x) node.y = min(left.y, right.y) node.w = max(left.x + left.w, right.x + right.w) - node.x node.h = max(left.y + left.h, right.y + right.h) - node.y # create a corridor between the two lower nodes if node.horizontal: # vertical corridor if left.x + left.w - 1 < right.x or right.x + right.w - 1 < left.x: # no overlapping zone. we need a Z shaped corridor x1 = libtcod.random_get_int(None, left.x, left.x + left.w - 1) x2 = libtcod.random_get_int(None, right.x, right.x + right.w - 1) y = libtcod.random_get_int(None, left.y + left.h, right.y) vline_up(bsp_map, x1, y - 1) hline(bsp_map, x1, y, x2) vline_down(bsp_map, x2, y + 1) else: # straight vertical corridor minx = max(left.x, right.x) maxx = min(left.x + left.w - 1, right.x + right.w - 1) x = libtcod.random_get_int(None, minx, maxx) vline_down(bsp_map, x, right.y) vline_up(bsp_map, x, right.y - 1) else: # horizontal corridor if left.y + left.h - 1 < right.y or right.y + right.h - 1 < left.y: # no overlapping zone. we need a Z shaped corridor y1 = libtcod.random_get_int(None, left.y, left.y + left.h - 1) y2 = libtcod.random_get_int(None, right.y, right.y + right.h - 1) x = libtcod.random_get_int(None, left.x + left.w, right.x) hline_left(bsp_map, x - 1, y1) vline(bsp_map, x, y1, y2) hline_right(bsp_map, x + 1, y2) else: # straight horizontal corridor miny = max(left.y, right.y) maxy = min(left.y + left.h - 1, right.y + right.h - 1) y = libtcod.random_get_int(None, miny, maxy) hline_left(bsp_map, right.x - 1, y) hline_right(bsp_map, right.x, y) return True bsp = None bsp_generate = True bsp_refresh = False def render_bsp(first, key, mouse): global bsp, bsp_generate, bsp_refresh, bsp_map global bsp_random_room, bsp_room_walls, bsp_depth, bsp_min_room_size if bsp_generate or bsp_refresh: # dungeon generation if bsp is None: # create the bsp bsp = libtcod.bsp_new_with_size(0, 0, SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT) else: # restore the nodes size libtcod.bsp_resize(bsp, 0, 0, SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT) bsp_map = list() for x in range(SAMPLE_SCREEN_WIDTH): bsp_map.append([False] * SAMPLE_SCREEN_HEIGHT) if bsp_generate: # build a new random bsp tree libtcod.bsp_remove_sons(bsp) if bsp_room_walls: libtcod.bsp_split_recursive(bsp, 0, bsp_depth, bsp_min_room_size + 1, bsp_min_room_size + 1, 1.5, 1.5) else: libtcod.bsp_split_recursive(bsp, 0, bsp_depth, bsp_min_room_size, bsp_min_room_size, 1.5, 1.5) # create the dungeon from the bsp libtcod.bsp_traverse_inverted_level_order(bsp, traverse_node) bsp_generate = False bsp_refresh = False libtcod.console_clear(sample_console) libtcod.console_set_default_foreground(sample_console, libtcod.white) rooms = 'OFF' if bsp_random_room: rooms = 'ON' libtcod.console_print(sample_console, 1, 1, "ENTER : rebuild bsp\n" "SPACE : rebuild dungeon\n" "+-: bsp depth %d\n" "*/: room size %d\n" "1 : random room size %s" % (bsp_depth, bsp_min_room_size, rooms)) if bsp_random_room: walls = 'OFF' if bsp_room_walls: walls ='ON' libtcod.console_print(sample_console, 1, 6, '2 : room walls %s' % walls) # render the level for y in range(SAMPLE_SCREEN_HEIGHT): for x in range(SAMPLE_SCREEN_WIDTH): if not bsp_map[x][y]: libtcod.console_set_char_background(sample_console, x, y, fov_dark_wall, libtcod.BKGND_SET) else: libtcod.console_set_char_background(sample_console, x, y, fov_dark_ground, libtcod.BKGND_SET) if key.vk in (libtcod.KEY_ENTER ,libtcod.KEY_KPENTER): bsp_generate = True elif key.c==ord(' '): bsp_refresh = True elif key.text == b"+": bsp_depth += 1 bsp_generate = True elif key.text == b"-" and bsp_depth > 1: bsp_depth -= 1 bsp_generate = True elif key.text == b"*": bsp_min_room_size += 1 bsp_generate = True elif key.text == b"/" and bsp_min_room_size > 2: bsp_min_room_size -= 1 bsp_generate = True elif key.c == ord('1') or key.vk in (libtcod.KEY_1, libtcod.KEY_KP1): bsp_random_room = not bsp_random_room if not bsp_random_room: bsp_room_walls = True bsp_refresh = True elif key.c == ord('2') or key.vk in (libtcod.KEY_2, libtcod.KEY_KP2): bsp_room_walls = not bsp_room_walls bsp_refresh = True ############################################# # image sample ############################################# img = None img_circle = None img_blue = libtcod.Color(0, 0, 255) img_green = libtcod.Color(0, 255, 0) def render_image(first, key, mouse): global img,img_circle,img_blue,img_green if img is None: img = libtcod.image_load(os.path.join(data_path,'img','skull.png')) libtcod.image_set_key_color(img,libtcod.black) img_circle = libtcod.image_load(os.path.join(data_path,'img','circle.png')) if first: libtcod.sys_set_fps(30) libtcod.console_set_default_background(sample_console, libtcod.black) libtcod.console_clear(sample_console) x = SAMPLE_SCREEN_WIDTH / 2 + math.cos(libtcod.sys_elapsed_seconds()) * 10.0 y = float(SAMPLE_SCREEN_HEIGHT / 2) scalex=0.2 + 1.8 * (1.0 + math.cos(libtcod.sys_elapsed_seconds() / 2)) / 2.0 scaley = scalex angle = libtcod.sys_elapsed_seconds() elapsed = libtcod.sys_elapsed_milli() // 2000 if elapsed & 1 != 0: # split the color channels of circle.png # the red channel libtcod.console_set_default_background(sample_console, libtcod.red) libtcod.console_rect(sample_console, 0, 3, 15, 15, False, libtcod.BKGND_SET) libtcod.image_blit_rect(img_circle, sample_console, 0, 3, -1, -1, libtcod.BKGND_MULTIPLY) # the green channel libtcod.console_set_default_background(sample_console, img_green) libtcod.console_rect(sample_console, 15, 3, 15, 15, False, libtcod.BKGND_SET) libtcod.image_blit_rect(img_circle,sample_console, 15, 3, -1, -1, libtcod.BKGND_MULTIPLY) # the blue channel libtcod.console_set_default_background(sample_console, img_blue) libtcod.console_rect(sample_console, 30, 3, 15, 15, False, libtcod.BKGND_SET) libtcod.image_blit_rect(img_circle, sample_console, 30, 3, -1, -1, libtcod.BKGND_MULTIPLY) else: # render circle.png with normal blitting libtcod.image_blit_rect(img_circle, sample_console, 0, 3, -1, -1, libtcod.BKGND_SET) libtcod.image_blit_rect(img_circle, sample_console, 15, 3, -1, -1, libtcod.BKGND_SET) libtcod.image_blit_rect(img_circle, sample_console, 30, 3, -1, -1, libtcod.BKGND_SET) libtcod.image_blit(img, sample_console, x, y, libtcod.BKGND_SET, scalex, scaley, angle) ############################################# # mouse sample ############################################# mouse_lbut = 0 mouse_mbut = 0 mouse_rbut = 0 def render_mouse(first, key, mouse): global mouse_lbut global mouse_mbut global mouse_rbut butstatus=('OFF', 'ON') if first: libtcod.console_set_default_background(sample_console, libtcod.grey) libtcod.console_set_default_foreground(sample_console, libtcod.light_yellow) libtcod.mouse_move(320, 200) libtcod.mouse_show_cursor(True) libtcod.sys_set_fps(30) libtcod.console_clear(sample_console) if mouse.lbutton_pressed: mouse_lbut = 1 - mouse_lbut if mouse.rbutton_pressed: mouse_rbut = 1 - mouse_rbut if mouse.mbutton_pressed: mouse_mbut = 1 - mouse_mbut wheel="" if mouse.wheel_up : wheel="UP" elif mouse.wheel_down : wheel="DOWN" activemsg="APPLICATION INACTIVE" if libtcod.console_is_active() : activemsg="" focusmsg="OUT OF FOCUS" if libtcod.console_has_mouse_focus() : focusmsg="" libtcod.console_print(sample_console, 1, 1, "%s\n" "Mouse position : %4dx%4d %s\n" "Mouse cell : %4dx%4d\n" "Mouse movement : %4dx%4d\n" "Left button : %s (toggle %s)\n" "Right button : %s (toggle %s)\n" "Middle button : %s (toggle %s)\n" "Wheel : %s" % (activemsg, mouse.x, mouse.y, focusmsg, mouse.cx, mouse.cy, mouse.dx, mouse.dy, butstatus[mouse.lbutton], butstatus[mouse_lbut], butstatus[mouse.rbutton], butstatus[mouse_rbut], butstatus[mouse.mbutton], butstatus[mouse_mbut], wheel)) libtcod.console_print(sample_console, 1, 10, "1 : Hide cursor\n2 : Show cursor") if key.c == ord('1'): libtcod.mouse_show_cursor(False) elif key.c == ord('2'): libtcod.mouse_show_cursor(True) ############################################# # name generator sample ############################################# ng_curset = 0 ng_nbsets = 0 ng_delay = 0.0 ng_names = [] ng_sets = None def render_name(first, key, mouse): global ng_curset global ng_nbsets global ng_delay global ng_names global ng_sets if ng_nbsets == 0: # parse all *.cfg files in data/namegen for file in os.listdir(os.path.join(data_path,'namegen')) : if file.find('.cfg') > 0 : libtcod.namegen_parse(os.path.join(data_path,'namegen',file)) # get the sets list ng_sets=libtcod.namegen_get_sets() print (ng_sets) ng_nbsets=len(ng_sets) if first: libtcod.sys_set_fps(30) while len(ng_names)> 15: ng_names.pop(0) libtcod.console_clear(sample_console) libtcod.console_set_default_foreground(sample_console,libtcod.white) libtcod.console_print(sample_console,1,1,"%s\n\n+ : next generator\n- : prev generator" % ng_sets[ng_curset]) for i in range(len(ng_names)) : libtcod.console_print_ex(sample_console,SAMPLE_SCREEN_WIDTH-2,2+i, libtcod.BKGND_NONE,libtcod.RIGHT,ng_names[i]) ng_delay += libtcod.sys_get_last_frame_length() if ng_delay > 0.5 : ng_delay -= 0.5 ng_names.append(libtcod.namegen_generate(ng_sets[ng_curset])) if key.text == b"+": ng_curset += 1 if ng_curset == ng_nbsets : ng_curset=0 ng_names.append("======") elif key.text == b"-": ng_curset -= 1 if ng_curset < 0 : ng_curset=ng_nbsets-1 ng_names.append("======") ############################################# # Python fast render sample ############################################# try: #import NumPy import numpy as np numpy_available = True except ImportError: numpy_available = False use_numpy = numpy_available #default option SCREEN_W = SAMPLE_SCREEN_WIDTH SCREEN_H = SAMPLE_SCREEN_HEIGHT HALF_W = SCREEN_W // 2 HALF_H = SCREEN_H // 2 RES_U = 80 #texture resolution RES_V = 80 TEX_STRETCH = 5 #texture stretching with tunnel depth SPEED = 15 LIGHT_BRIGHTNESS = 3.5 #brightness multiplier for all lights (changes their radius) LIGHTS_CHANCE = 0.07 #chance of a light appearing MAX_LIGHTS = 6 MIN_LIGHT_STRENGTH = 0.2 LIGHT_UPDATE = 0.05 #how much the ambient light changes to reflect current light sources AMBIENT_LIGHT = 0.8 #brightness of tunnel texture #the coordinates of all tiles in the screen, as numpy arrays. example: (4x3 pixels screen) #xc = [[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]] #yc = [[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3]] if numpy_available: (xc, yc) = np.meshgrid(range(SCREEN_W), range(SCREEN_H)) #translate coordinates of all pixels to center xc = xc - HALF_W yc = yc - HALF_H noise2d = libtcod.noise_new(2, 0.5, 2.0) if numpy_available: #the texture starts empty texture = np.zeros((RES_U, RES_V)) #create lists to work without numpy texture2 = [0 for i in range(RES_U * RES_V)] brightness2 = [0 for i in range(SCREEN_W * SCREEN_H)] R2 = [0 for i in range(SCREEN_W * SCREEN_H)] G2 = [0 for i in range(SCREEN_W * SCREEN_H)] B2 = [0 for i in range(SCREEN_W * SCREEN_H)] class Light: def __init__(self, x, y, z, r, g, b, strength): self.x, self.y, self.z = x, y, z #pos. self.r, self.g, self.b = r, g, b #color self.strength = strength #between 0 and 1, defines brightness def render_py(first, key, mouse): global use_numpy, frac_t, abs_t, lights, tex_r, tex_g, tex_b, xc, yc, texture, texture2, brightness2, R2, G2, B2 if key.c == ord(' ') and numpy_available: #toggle renderer use_numpy = not use_numpy first = True if first: #initialize stuff libtcod.sys_set_fps(0) libtcod.console_clear(sample_console) #render status message if not numpy_available: text = 'NumPy uninstalled, using default renderer' elif use_numpy: text = 'Renderer: NumPy \nSpacebar to change' else: text = 'Renderer: default\nSpacebar to change' libtcod.console_set_default_foreground(sample_console,libtcod.white) libtcod.console_print(sample_console, 1, SCREEN_H - 3, text) frac_t = RES_V - 1 #time is represented in number of pixels of the texture, start later in time to initialize texture abs_t = RES_V - 1 lights = [] #lights list, and current color of the tunnel texture tex_r, tex_g, tex_b = 0, 0, 0 time_delta = libtcod.sys_get_last_frame_length() * SPEED #advance time frac_t += time_delta #increase fractional (always < 1.0) time abs_t += time_delta #increase absolute elapsed time int_t = int(frac_t) #integer time units that passed this frame (number of texture pixels to advance) frac_t -= int_t #keep this < 1.0 #change texture color according to presence of lights (basically, sum them #to get ambient light and smoothly change the current color into that) ambient_r = AMBIENT_LIGHT * sum([light.r * light.strength for light in lights]) ambient_g = AMBIENT_LIGHT * sum([light.g * light.strength for light in lights]) ambient_b = AMBIENT_LIGHT * sum([light.b * light.strength for light in lights]) alpha = LIGHT_UPDATE * time_delta tex_r = tex_r * (1 - alpha) + ambient_r * alpha tex_g = tex_g * (1 - alpha) + ambient_g * alpha tex_b = tex_b * (1 - alpha) + ambient_b * alpha if int_t >= 1: #roll texture (ie, advance in tunnel) according to int_t int_t = int_t % RES_V #can't roll more than the texture's size (can happen when time_delta is large) int_abs_t = int(abs_t) #new pixels are based on absolute elapsed time if use_numpy: texture = np.roll(texture, -int_t, 1) #replace new stretch of texture with new values for v in range(RES_V - int_t, RES_V): for u in range(0, RES_U): tex_v = (v + int_abs_t) / float(RES_V) texture[u,v] = (libtcod.noise_get_fbm(noise2d, [u/float(RES_U), tex_v], 32.0) + libtcod.noise_get_fbm(noise2d, [1 - u/float(RES_U), tex_v], 32.0)) else: #"roll" texture, without numpy temp = texture2[0 : RES_U*int_t] texture2 = texture2[RES_U*int_t : ] texture2.extend(temp) #replace new stretch of texture with new values for v in range(RES_V - int_t, RES_V): for u in range(0, RES_U): tex_v = (v + int_abs_t) / float(RES_V) texture2[u + v*RES_U] = ( libtcod.noise_get_fbm(noise2d, [u/float(RES_U), tex_v], 32.0) + libtcod.noise_get_fbm(noise2d, [1 - u/float(RES_U), tex_v], 32.0)) if use_numpy: #squared distance from center, clipped to sensible minimum and maximum values sqr_dist = xc**2 + yc**2 sqr_dist = sqr_dist.clip(1.0 / RES_V, RES_V**2) #one coordinate into the texture, represents depth in the tunnel v = TEX_STRETCH * float(RES_V) / sqr_dist + frac_t v = v.clip(0, RES_V - 1) #another coordinate, represents rotation around the tunnel u = np.mod(RES_U * (np.arctan2(yc, xc) / (2 * np.pi) + 0.5), RES_U) #retrieve corresponding pixels from texture brightness = texture[u.astype(int), v.astype(int)] / 4.0 + 0.5 #use the brightness map to compose the final color of the tunnel R = brightness * tex_r G = brightness * tex_g B = brightness * tex_b else: i = 0 for y in range(-HALF_H, HALF_H): for x in range(-HALF_W, HALF_W): #squared distance from center, clipped to sensible minimum and maximum values sqr_dist = x**2 + y**2 sqr_dist = min(max(sqr_dist, 1.0 / RES_V), RES_V**2) #one coordinate into the texture, represents depth in the tunnel v = TEX_STRETCH * float(RES_V) / sqr_dist + frac_t v = min(v, RES_V - 1) #another coordinate, represents rotation around the tunnel u = (RES_U * (math.atan2(y, x) / (2 * math.pi) + 0.5)) % RES_U #retrieve corresponding pixels from texture brightness = texture2[int(u) + int(v)*RES_U] / 4.0 + 0.5 #use the brightness map to compose the final color of the tunnel R2[i] = brightness * tex_r G2[i] = brightness * tex_g B2[i] = brightness * tex_b i += 1 #create new light source if libtcod.random_get_float(0, 0, 1) <= time_delta * LIGHTS_CHANCE and len(lights) < MAX_LIGHTS: x = libtcod.random_get_float(0, -0.5, 0.5) y = libtcod.random_get_float(0, -0.5, 0.5) strength = libtcod.random_get_float(0, MIN_LIGHT_STRENGTH, 1.0) color = libtcod.Color(0, 0, 0) #create bright colors with random hue hue = libtcod.random_get_float(0, 0, 360) libtcod.color_set_hsv(color, hue, 0.5, strength) lights.append(Light(x, y, TEX_STRETCH, color.r, color.g, color.b, strength)) #eliminate lights that are going to be out of view lights = [light for light in lights if light.z - time_delta > 1.0 / RES_V] for light in lights: #render lights #move light's Z coordinate with time, then project its XYZ coordinates to screen-space light.z -= float(time_delta) / TEX_STRETCH xl = light.x / light.z * SCREEN_H yl = light.y / light.z * SCREEN_H if use_numpy: #calculate brightness of light according to distance from viewer and strength, #then calculate brightness of each pixel with inverse square distance law light_brightness = LIGHT_BRIGHTNESS * light.strength * (1.0 - light.z / TEX_STRETCH) brightness = light_brightness / ((xc - xl)**2 + (yc - yl)**2) #make all pixels shine around this light R += brightness * light.r G += brightness * light.g B += brightness * light.b else: i = 0 #same, without numpy for y in range(-HALF_H, HALF_H): for x in range(-HALF_W, HALF_W): light_brightness = LIGHT_BRIGHTNESS * light.strength * (1.0 - light.z / TEX_STRETCH) brightness = light_brightness / ((x - xl)**2 + (y - yl)**2) R2[i] += brightness * light.r G2[i] += brightness * light.g B2[i] += brightness * light.b i += 1 if use_numpy: #truncate values R = R.clip(0, 255) G = G.clip(0, 255) B = B.clip(0, 255) #fill the screen with these background colors libtcod.console_fill_background(sample_console, R, G, B) else: #truncate and convert to integer R2 = [int(min(r, 255)) for r in R2] G2 = [int(min(g, 255)) for g in G2] B2 = [int(min(b, 255)) for b in B2] #fill the screen with these background colors libtcod.console_fill_background(sample_console, R2, G2, B2) ############################################# # main loop ############################################# class Sample: def __init__(self, name, func): self.name = name self.func = func samples = (Sample(' True colors ', render_colors), Sample(' Offscreen console ', render_offscreen), Sample(' Line drawing ', render_lines), Sample(' Noise ', render_noise), Sample(' Field of view ', render_fov), Sample(' Path finding ', render_path), Sample(' Bsp toolkit ', render_bsp), Sample(' Image toolkit ', render_image), Sample(' Mouse support ', render_mouse), Sample(' Name generator ', render_name), Sample(' Python fast render ', render_py)) cur_sample = 0 credits_end = False first = True cur_renderer = 0 renderer_name=('F1 GLSL ','F2 OPENGL ','F3 SDL ') key=libtcod.Key() mouse=libtcod.Mouse() while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS|libtcod.EVENT_MOUSE,key,mouse) # render the sample samples[cur_sample].func(first, key, mouse) first = False libtcod.console_blit(sample_console, 0, 0, SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT, 0, SAMPLE_SCREEN_X, SAMPLE_SCREEN_Y) # render credits if not credits_end: credits_end = libtcod.console_credits_render(60, 43, 0) # render sample list for i in range(len(samples)): if i == cur_sample: libtcod.console_set_default_foreground(None, libtcod.white) libtcod.console_set_default_background(None, libtcod.light_blue) else: libtcod.console_set_default_foreground(None, libtcod.grey) libtcod.console_set_default_background(None, libtcod.black) libtcod.console_print_ex(None, 2, 46 - (len(samples) - i), libtcod.BKGND_SET, libtcod.LEFT, samples[i].name) # render stats libtcod.console_set_default_foreground(None, libtcod.grey) libtcod.console_print_ex(None, 79, 46, libtcod.BKGND_NONE, libtcod.RIGHT, 'last frame : %3d ms (%3d fps)' % (int(libtcod.sys_get_last_frame_length() * 1000.0), libtcod.sys_get_fps())) libtcod.console_print_ex(None, 79, 47, libtcod.BKGND_NONE, libtcod.RIGHT, 'elapsed : %8d ms %4.2fs' % (libtcod.sys_elapsed_milli(), libtcod.sys_elapsed_seconds())) cur_renderer=libtcod.sys_get_renderer() libtcod.console_set_default_foreground(None,libtcod.grey) libtcod.console_set_default_background(None,libtcod.black) libtcod.console_print_ex(None,42,46-(libtcod.NB_RENDERERS+1),libtcod.BKGND_SET, libtcod.LEFT, "Renderer :") for i in range(libtcod.NB_RENDERERS) : if i==cur_renderer : libtcod.console_set_default_foreground(None,libtcod.white) libtcod.console_set_default_background(None,libtcod.light_blue) else : libtcod.console_set_default_foreground(None,libtcod.grey) libtcod.console_set_default_background(None,libtcod.black) libtcod.console_print_ex(None,42,46-(libtcod.NB_RENDERERS-i),libtcod.BKGND_SET,libtcod.LEFT,renderer_name[i]) # key handler if key.vk == libtcod.KEY_DOWN: cur_sample = (cur_sample+1) % len(samples) first = True elif key.vk == libtcod.KEY_UP: cur_sample = (cur_sample-1) % len(samples) first = True elif key.vk == libtcod.KEY_ENTER and key.lalt: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_PRINTSCREEN or key.c == 'p': print ("screenshot") if key.lalt : libtcod.console_save_apf(None,"samples.apf") print ("apf") else : libtcod.sys_save_screenshot() print ("png") elif key.vk == libtcod.KEY_ESCAPE: break elif key.vk == libtcod.KEY_F1: libtcod.sys_set_renderer(libtcod.RENDERER_GLSL) elif key.vk == libtcod.KEY_F2: libtcod.sys_set_renderer(libtcod.RENDERER_OPENGL) elif key.vk == libtcod.KEY_F3: libtcod.sys_set_renderer(libtcod.RENDERER_SDL) libtcod.console_flush() libtcod-1.6.4+dfsg/python/setup.cfg000066400000000000000000000003661321276576200172430ustar00rootroot00000000000000[bdist_wheel] ; this ctypes module works on both Python 2 and 3 universal = 1 [build_make] ; the make command raises errors on DLL's that are already built ignore_errors = 1 [aliases] test=pytest [tool:pytest] addopts = tests/ --cov=libtcodpy libtcod-1.6.4+dfsg/python/setup.py000066400000000000000000000076261321276576200171420ustar00rootroot00000000000000#!/usr/bin/env python import sys import os from distutils.command.build import build as orig_build from distutils.util import get_platform from distutils import file_util from setuptools import setup, Command class build_make(Command): description = "run the makefile and include the libraries in the build" user_options = [('ignore-errors', 'i', "ignore errors from makefile commands"), ] boolean_options = ['ignore-errors'] def initialize_options(self): self.build_lib = None self.ignore_errors = False self.makefile = None self.make_data = None # {package: files} place_dll_dir = 'libtcodpy' if 'linux' in sys.platform: self.makefile = 'makefiles/makefile-linux' self.make_data = {place_dll_dir: ['libtcod.so']} elif 'haiku' in sys.platform: self.makefile = 'makefiles/makefile-haiku' self.make_data = {place_dll_dir: ['libtcod.so']} elif 'win' in sys.platform: self.makefile = 'makefiles/makefile-mingw-sdl2' self.make_data = {place_dll_dir: ['libtcod-mingw.dll', 'SDL2.dll']} else: raise StandardError('No makefile exists for the %s platform' % sys.platform) def finalize_options(self): self.set_undefined_options('build', ('build_lib', 'build_lib'),) def run(self): cmd = ['make', '-f', self.makefile,'release'] if self.ignore_errors: cmd += ['--ignore-errors'] if self.dry_run: cmd += ['--dry-run'] self.spawn(cmd) for directory, files in self.make_data.items(): for file in files: self.copy_file(os.path.join('.', file), os.path.join(self.build_lib, directory, file)) class build(orig_build): def initialize_options(self): 'add the platform name to the build dir to prevent conflicts' orig_build.initialize_options(self) plat_name = self.plat_name or get_platform() self.build_lib = os.path.join(self.build_base, 'lib.%s' % plat_name) # add build_make as a subcommand sub_commands = orig_build.sub_commands + [('build_make', None)] cmdclass={'build': build, 'build_make': build_make} try: from wheel.bdist_wheel import bdist_wheel as orig_bdist_wheel class bdist_wheel(orig_bdist_wheel): """ctypes libraries are "platform specific" "pure Python" modules. There's no way to tell bdist_wheel this without overwriting its methods """ description = "create a ctypes wheel distribution" def get_tag(self): # modified to add the platform tag to pure libraries # no other changes impl, abi, plat = orig_bdist_wheel.get_tag(self) plat_name = self.plat_name if plat_name is None: plat_name = get_platform() plat_name = plat_name.replace('-', '_').replace('.', '_') return (impl, abi, plat_name) cmdclass['bdist_wheel'] = bdist_wheel except ImportError: pass needs_pytest = {'pytest', 'test', 'ptr'}.intersection(sys.argv) pytest_runner = ['pytest-runner'] if needs_pytest else [] setup( # public name, e.g. > pip install libtcod name='libtcod', # generic first release version version = '0.1.0', # package named to be compatible with the tutorial packages=['libtcodpy'], # use added and modified commands # disabled at this moment #cmdclass=cmdclass, # important metadata url = 'https://bitbucket.org/libtcod/libtcod', maintainer = '', maintainer_email = '', # used for test command setup_requires = pytest_runner, tests_require = ['pytest', 'pytest-cov'], # optional metadata for pypi description = '', license = 'Revised BSD License', # 3-clause BSD license ) libtcod-1.6.4+dfsg/python/tests/000077500000000000000000000000001321276576200165575ustar00rootroot00000000000000libtcod-1.6.4+dfsg/python/tests/conftest.py000066400000000000000000000056441321276576200207670ustar00rootroot00000000000000 import random import pytest import libtcodpy FONT_FILE = '../terminal.png' WIDTH = 12 HEIGHT = 10 TITLE = 'libtcodpy tests' FULLSCREEN = False RENDERER = libtcodpy.RENDERER_SDL @pytest.fixture(scope="module") def session_console(): libtcodpy.console_set_custom_font(FONT_FILE) console = libtcodpy.console_init_root(WIDTH, HEIGHT, TITLE, FULLSCREEN) assert libtcodpy.console_get_width(console) == WIDTH assert libtcodpy.console_get_height(console) == HEIGHT assert libtcodpy.console_is_fullscreen() == FULLSCREEN libtcodpy.console_set_window_title(TITLE) assert not libtcodpy.console_is_window_closed() libtcodpy.sys_get_current_resolution() libtcodpy.sys_get_char_size() libtcodpy.sys_set_renderer(RENDERER) libtcodpy.sys_get_renderer() yield console libtcodpy.console_delete(console) @pytest.fixture(scope="function") def console(session_console): """Return a root console. Be sure to use this fixture if the GUI needs to be initialized for a test. """ console = session_console libtcodpy.console_flush() libtcodpy.console_set_default_foreground(console, libtcodpy.white) libtcodpy.console_set_default_background(console, libtcodpy.black) libtcodpy.console_set_background_flag(console, libtcodpy.BKGND_SET) libtcodpy.console_set_alignment(console, libtcodpy.LEFT) libtcodpy.console_clear(console) return console @pytest.fixture() def offscreen(console): """Return an off-screen console with the same size as the root console.""" offscreen = libtcodpy.console_new( libtcodpy.console_get_width(console), libtcodpy.console_get_height(console), ) yield offscreen libtcodpy.console_delete(offscreen) @pytest.fixture() def fg(): return libtcodpy.Color(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) @pytest.fixture() def bg(): return libtcodpy.Color(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) try: unichr except NameError: unichr = chr def ch_ascii_int(): return random.randint(0x21, 0x7f) def ch_ascii_str(): return chr(ch_ascii_int()) def ch_latin1_int(): return random.randint(0x80, 0xff) def ch_latin1_str(): return chr(ch_latin1_int()) def ch_bmp_int(): # Basic Multilingual Plane, before surrogates return random.randint(0x100, 0xd7ff) def ch_bmp_str(): return unichr(ch_bmp_int()) def ch_smp_int(): return random.randint(0x10000, 0x1f9ff) def ch_smp_str(): return unichr(ch_bmp_int()) @pytest.fixture(params=['ascii_int', 'ascii_str', 'latin1_int', 'latin1_str', #'bmp_int', 'bmp_str', # causes crashes ]) def ch(request): """Test with multiple types of ascii/latin1 characters""" return globals()['ch_%s' % request.param]() libtcod-1.6.4+dfsg/python/tests/test_libtcodpy.py000066400000000000000000000537471321276576200222010ustar00rootroot00000000000000#!/usr/bin/env python import pytest import shutil import tempfile import unittest try: import numpy except ImportError: numpy = None import libtcodpy def test_console_behaviour(console): assert not console @pytest.mark.skip('takes too long') def test_credits_long(console): libtcodpy.console_credits() def test_credits(console): libtcodpy.console_credits_render(0, 0, True) libtcodpy.console_credits_reset() def assert_char(console, x, y, ch=None, fg=None, bg=None): if ch is not None: try: ch = ord(ch) except TypeError: pass assert libtcodpy.console_get_char(console, x, y) == ch if fg is not None: assert libtcodpy.console_get_char_foreground(console, x, y) == fg if bg is not None: assert libtcodpy.console_get_char_background(console, x, y) == bg def test_console_defaults(console, fg, bg): libtcodpy.console_set_default_foreground(console, fg) libtcodpy.console_set_default_background(console, bg) libtcodpy.console_clear(console) assert_char(console, 0, 0, None, fg, bg) def test_console_set_char_background(console, bg): libtcodpy.console_set_char_background(console, 0, 0, bg, libtcodpy.BKGND_SET) assert_char(console, 0, 0, bg=bg) def test_console_set_char_foreground(console, fg): libtcodpy.console_set_char_foreground(console, 0, 0, fg) assert_char(console, 0, 0, fg=fg) def test_console_set_char(console, ch): libtcodpy.console_set_char(console, 0, 0, ch) assert_char(console, 0, 0, ch=ch) def test_console_put_char(console, ch): libtcodpy.console_put_char(console, 0, 0, ch, libtcodpy.BKGND_SET) assert_char(console, 0, 0, ch=ch) def console_put_char_ex(console, ch, fg, bg): libtcodpy.console_put_char_ex(console, 0, 0, ch, fg, bg) assert_char(console, 0, 0, ch=ch, fg=fg, bg=bg) def test_console_printing(console, fg, bg): libtcodpy.console_set_background_flag(console, libtcodpy.BKGND_SET) assert (libtcodpy.console_get_background_flag(console) == libtcodpy.BKGND_SET) libtcodpy.console_set_alignment(console, libtcodpy.LEFT) assert (libtcodpy.console_get_alignment(console) == libtcodpy.LEFT) libtcodpy.console_print(console, 0, 0, 'print') libtcodpy.console_print_ex(console, 0, 0, libtcodpy.BKGND_SET, libtcodpy.LEFT, 'print ex') assert (libtcodpy.console_print_rect( console, 0, 0, 8, 8, 'print rect') > 0 ) assert (libtcodpy.console_print_rect_ex( console, 0, 0, 8, 8, libtcodpy.BKGND_SET, libtcodpy.LEFT, 'print rect ex') > 0 ) assert (libtcodpy.console_get_height_rect( console, 0, 0, 8, 8, 'get height') > 0 ) libtcodpy.console_set_color_control(libtcodpy.COLCTRL_1, fg, bg) def test_console_printing_advanced(console): libtcodpy.console_rect(console, 0, 0, 4, 4, False, libtcodpy.BKGND_SET) libtcodpy.console_hline(console, 0, 0, 4) libtcodpy.console_vline(console, 0, 0, 4) libtcodpy.console_print_frame(console, 0, 0, 11, 11) def test_console_fade(console): libtcodpy.console_set_fade(0, libtcodpy.Color(0, 0, 0)) libtcodpy.console_get_fade() libtcodpy.console_get_fading_color() def assertConsolesEqual(a, b): for y in range(libtcodpy.console_get_height(a)): for x in range(libtcodpy.console_get_width(a)): assert libtcodpy.console_get_char(a, x, y) == \ libtcodpy.console_get_char(b, x, y) assert libtcodpy.console_get_char_foreground(a, x, y) == \ libtcodpy.console_get_char_foreground(b, x, y) assert libtcodpy.console_get_char_background(a, x, y) == \ libtcodpy.console_get_char_background(b, x, y) def test_console_blit(console, offscreen): libtcodpy.console_print(offscreen, 0, 0, 'test') libtcodpy.console_blit(offscreen, 0, 0, 0, 0, console, 0, 0, 1, 1) assertConsolesEqual(console, offscreen) libtcodpy.console_set_key_color(offscreen, libtcodpy.black) def test_console_asc_read_write(console, offscreen, tmpdir): libtcodpy.console_print(console, 0, 0, 'test') asc_file = tmpdir.join('test.asc').strpath assert libtcodpy.console_save_asc(console, asc_file) assert libtcodpy.console_load_asc(offscreen, asc_file) assertConsolesEqual(console, offscreen) def test_console_apf_read_write(console, offscreen, tmpdir): libtcodpy.console_print(console, 0, 0, 'test') apf_file = tmpdir.join('test.apf').strpath assert libtcodpy.console_save_apf(console, apf_file) assert libtcodpy.console_load_apf(offscreen, apf_file) assertConsolesEqual(console, offscreen) def test_console_rexpaint_load_test_file(console): xp_console = libtcodpy.console_from_xp('../data/rexpaint/test.xp') assert xp_console assert libtcodpy.console_get_char(xp_console, 0, 0) == ord('T') assert libtcodpy.console_get_char(xp_console, 1, 0) == ord('e') assert (libtcodpy.console_get_char_background(xp_console, 0, 1) == libtcodpy.Color(255, 0, 0)) assert (libtcodpy.console_get_char_background(xp_console, 1, 1) == libtcodpy.Color(0, 255, 0)) assert (libtcodpy.console_get_char_background(xp_console, 2, 1) == libtcodpy.Color(0, 0, 255)) def test_console_rexpaint_save_load(console, tmpdir, ch, fg, bg): libtcodpy.console_print(console, 0, 0, 'test') libtcodpy.console_put_char_ex(console, 1, 1, ch, fg, bg) xp_file = tmpdir.join('test.xp').strpath assert libtcodpy.console_save_xp(console, xp_file, 1) xp_console = libtcodpy.console_from_xp(xp_file) assert xp_console assertConsolesEqual(console, xp_console) assert libtcodpy.console_load_xp(None, xp_file) assertConsolesEqual(console, xp_console) def test_console_rexpaint_list_save_load(console, tmpdir): con1 = libtcodpy.console_new(8, 2) con2 = libtcodpy.console_new(8, 2) libtcodpy.console_print(con1, 0, 0, 'hello') libtcodpy.console_print(con2, 0, 0, 'world') xp_file = tmpdir.join('test.xp').strpath assert libtcodpy.console_list_save_xp([con1, con2], xp_file, 1) for a, b in zip([con1, con2], libtcodpy.console_list_load_xp(xp_file)): assertConsolesEqual(a, b) libtcodpy.console_delete(a) libtcodpy.console_delete(b) def test_console_fullscreen(console): libtcodpy.console_set_fullscreen(False) def test_console_key_input(console): libtcodpy.console_check_for_keypress() libtcodpy.console_is_key_pressed(libtcodpy.KEY_ENTER) def test_console_fill_errors(console): with pytest.raises(TypeError): libtcodpy.console_fill_background(console, [0], [], []) with pytest.raises(TypeError): libtcodpy.console_fill_foreground(console, [0], [], []) def test_console_fill(console): width = libtcodpy.console_get_width(console) height = libtcodpy.console_get_height(console) fill = [i % 256 for i in range(width * height)] libtcodpy.console_fill_background(console, fill, fill, fill) libtcodpy.console_fill_foreground(console, fill, fill, fill) libtcodpy.console_fill_char(console, fill) # verify fill bg, fg, ch = [], [], [] for y in range(height): for x in range(width): bg.append(libtcodpy.console_get_char_background(console, x, y)[0]) fg.append(libtcodpy.console_get_char_foreground(console, x, y)[0]) ch.append(libtcodpy.console_get_char(console, x, y)) assert fill == bg assert fill == fg assert fill == ch @unittest.skipUnless(numpy, 'requires numpy module') def test_console_fill_numpy(console): width = libtcodpy.console_get_width(console) height = libtcodpy.console_get_height(console) fill = numpy.zeros((height, width), dtype=numpy.intc) for y in range(height): fill[y, :] = y % 256 libtcodpy.console_fill_background(console, fill, fill, fill) libtcodpy.console_fill_foreground(console, fill, fill, fill) libtcodpy.console_fill_char(console, fill) # verify fill bg = numpy.zeros((height, width), dtype=numpy.intc) fg = numpy.zeros((height, width), dtype=numpy.intc) ch = numpy.zeros((height, width), dtype=numpy.intc) for y in range(height): for x in range(width): bg[y, x] = libtcodpy.console_get_char_background(console, x, y)[0] fg[y, x] = libtcodpy.console_get_char_foreground(console, x, y)[0] ch[y, x] = libtcodpy.console_get_char(console, x, y) fill = fill.tolist() assert fill == bg.tolist() assert fill == fg.tolist() assert fill == ch.tolist() def test_console_buffer(console): buffer = libtcodpy.ConsoleBuffer( libtcodpy.console_get_width(console), libtcodpy.console_get_height(console), ) buffer = buffer.copy() buffer.set_fore(0, 0, 0, 0, 0, '@') buffer.set_back(0, 0, 0, 0, 0) buffer.set(0, 0, 0, 0, 0, 0, 0, 0, '@') buffer.blit(console) def test_console_buffer_error(console): buffer = libtcodpy.ConsoleBuffer(0, 0) with pytest.raises(ValueError): buffer.blit(console) def test_console_font_mapping(console): libtcodpy.console_map_ascii_code_to_font('@', 1, 1) libtcodpy.console_map_ascii_codes_to_font('@', 1, 0, 0) libtcodpy.console_map_string_to_font('@', 0, 0) def test_mouse(console): libtcodpy.mouse_show_cursor(True) libtcodpy.mouse_is_cursor_visible() mouse = libtcodpy.mouse_get_status() repr(mouse) libtcodpy.mouse_move(0, 0) def test_sys_time(console): libtcodpy.sys_set_fps(0) libtcodpy.sys_get_fps() libtcodpy.sys_get_last_frame_length() libtcodpy.sys_sleep_milli(0) libtcodpy.sys_elapsed_milli() libtcodpy.sys_elapsed_seconds() def test_sys_screenshot(console, tmpdir): libtcodpy.sys_save_screenshot(tmpdir.join('test.png').strpath) def test_sys_custom_render(console): escape = [] def sdl_callback(sdl_surface): escape.append(True) libtcodpy.console_set_dirty(0, 0, 0, 0) libtcodpy.sys_register_SDL_renderer(sdl_callback) libtcodpy.console_flush() assert escape, 'proof that sdl_callback was called' def test_image(console, tmpdir): img = libtcodpy.image_new(16, 16) libtcodpy.image_clear(img, libtcodpy.Color(0, 0, 0)) libtcodpy.image_invert(img) libtcodpy.image_hflip(img) libtcodpy.image_rotate90(img) libtcodpy.image_vflip(img) libtcodpy.image_scale(img, 24, 24) libtcodpy.image_set_key_color(img, libtcodpy.Color(255, 255, 255)) libtcodpy.image_get_alpha(img, 0, 0) libtcodpy.image_is_pixel_transparent(img, 0, 0) libtcodpy.image_get_size(img) libtcodpy.image_get_pixel(img, 0, 0) libtcodpy.image_get_mipmap_pixel(img, 0, 0, 1, 1) libtcodpy.image_put_pixel(img, 0, 0, libtcodpy.Color(255, 255, 255)) libtcodpy.image_blit(img, console, 0, 0, libtcodpy.BKGND_SET, 1, 1, 0) libtcodpy.image_blit_rect(img, console, 0, 0, 16, 16, libtcodpy.BKGND_SET) libtcodpy.image_blit_2x(img, console, 0, 0) libtcodpy.image_save(img, tmpdir.join('test.png').strpath) libtcodpy.image_delete(img) img = libtcodpy.image_from_console(console) libtcodpy.image_refresh_console(img, console) libtcodpy.image_delete(img) libtcodpy.image_delete(libtcodpy.image_load('../data/img/circle.png')) @pytest.mark.parametrize('sample', ['@', u'\u2603']) # Unicode snowman def test_clipboard(console, sample): saved = libtcodpy.sys_clipboard_get() try: libtcodpy.sys_clipboard_set(sample) assert libtcodpy.sys_clipboard_get() == sample finally: libtcodpy.sys_clipboard_set(saved) # arguments to test with and the results expected from these arguments LINE_ARGS = (-5, 0, 5, 10) EXCLUSIVE_RESULTS = [(-4, 1), (-3, 2), (-2, 3), (-1, 4), (0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10)] INCLUSIVE_RESULTS = [(-5, 0)] + EXCLUSIVE_RESULTS def test_line_step(): """ libtcodpy.line_init and libtcodpy.line_step """ libtcodpy.line_init(*LINE_ARGS) for expected_xy in EXCLUSIVE_RESULTS: assert libtcodpy.line_step() == expected_xy assert libtcodpy.line_step() == (None, None) def test_line(): """ tests normal use, lazy evaluation, and error propagation """ # test normal results test_result = [] def line_test(*test_xy): test_result.append(test_xy) return 1 assert libtcodpy.line(*LINE_ARGS, py_callback=line_test) == 1 assert test_result == INCLUSIVE_RESULTS # test lazy evaluation test_result = [] def return_false(*test_xy): test_result.append(test_xy) return False assert libtcodpy.line(*LINE_ARGS, py_callback=return_false) == 0 assert test_result == INCLUSIVE_RESULTS[:1] def test_line_iter(): """ libtcodpy.line_iter """ assert list(libtcodpy.line_iter(*LINE_ARGS)) == INCLUSIVE_RESULTS def test_bsp(): """ commented out statements work in libtcod-cffi """ bsp = libtcodpy.bsp_new_with_size(0, 0, 64, 64) repr(bsp) # test __repr__ on leaf libtcodpy.bsp_resize(bsp, 0, 0, 32, 32) assert bsp != None # test getter/setters bsp.x = bsp.x bsp.y = bsp.y bsp.w = bsp.w bsp.h = bsp.h bsp.position = bsp.position bsp.horizontal = bsp.horizontal bsp.level = bsp.level # cover functions on leaf #self.assertFalse(libtcodpy.bsp_left(bsp)) #self.assertFalse(libtcodpy.bsp_right(bsp)) #self.assertFalse(libtcodpy.bsp_father(bsp)) assert libtcodpy.bsp_is_leaf(bsp) assert libtcodpy.bsp_contains(bsp, 1, 1) #self.assertFalse(libtcodpy.bsp_contains(bsp, -1, -1)) #self.assertEqual(libtcodpy.bsp_find_node(bsp, 1, 1), bsp) #self.assertFalse(libtcodpy.bsp_find_node(bsp, -1, -1)) libtcodpy.bsp_split_once(bsp, False, 4) repr(bsp) # test __repr__ with parent libtcodpy.bsp_split_once(bsp, True, 4) repr(bsp) # cover functions on parent assert libtcodpy.bsp_left(bsp) assert libtcodpy.bsp_right(bsp) #self.assertFalse(libtcodpy.bsp_father(bsp)) assert not libtcodpy.bsp_is_leaf(bsp) #self.assertEqual(libtcodpy.bsp_father(libtcodpy.bsp_left(bsp)), bsp) #self.assertEqual(libtcodpy.bsp_father(libtcodpy.bsp_right(bsp)), bsp) libtcodpy.bsp_split_recursive(bsp, None, 4, 2, 2, 1.0, 1.0) # cover bsp_traverse def traverse(node, user_data): return True libtcodpy.bsp_traverse_pre_order(bsp, traverse) libtcodpy.bsp_traverse_in_order(bsp, traverse) libtcodpy.bsp_traverse_post_order(bsp, traverse) libtcodpy.bsp_traverse_level_order(bsp, traverse) libtcodpy.bsp_traverse_inverted_level_order(bsp, traverse) # test __repr__ on deleted node son = libtcodpy.bsp_left(bsp) libtcodpy.bsp_remove_sons(bsp) repr(son) libtcodpy.bsp_delete(bsp) def test_map(): map = libtcodpy.map_new(16, 16) assert libtcodpy.map_get_width(map) == 16 assert libtcodpy.map_get_height(map) == 16 libtcodpy.map_copy(map, map) libtcodpy.map_clear(map) libtcodpy.map_set_properties(map, 0, 0, True, True) assert libtcodpy.map_is_transparent(map, 0, 0) assert libtcodpy.map_is_walkable(map, 0, 0) libtcodpy.map_is_in_fov(map, 0, 0) libtcodpy.map_delete(map) def test_color(): color_a = libtcodpy.Color(0, 1, 2) assert list(color_a) == [0, 1, 2] assert color_a[0] == color_a.r assert color_a[1] == color_a.g assert color_a[2] == color_a.b color_a[1] = 3 color_a['b'] = color_a['b'] assert list(color_a) == [0, 3, 2] assert color_a == color_a color_b = libtcodpy.Color(255, 255, 255) assert color_a != color_b color = libtcodpy.color_lerp(color_a, color_b, 0.5) libtcodpy.color_set_hsv(color, 0, 0, 0) libtcodpy.color_get_hsv(color) libtcodpy.color_scale_HSV(color, 0, 0) def test_color_repr(): Color = libtcodpy.Color col = Color(0, 1, 2) assert eval(repr(col)) == col def test_color_math(): color_a = libtcodpy.Color(0, 1, 2) color_b = libtcodpy.Color(0, 10, 20) assert color_a + color_b == libtcodpy.Color(0, 11, 22) assert color_b - color_a == libtcodpy.Color(0, 9, 18) assert libtcodpy.Color(255, 255, 255) * color_a == color_a assert color_a * 100 == libtcodpy.Color(0, 100, 200) def test_color_gen_map(): colors = libtcodpy.color_gen_map([(0, 0, 0), (255, 255, 255)], [0, 8]) assert colors[0] == libtcodpy.Color(0, 0, 0) assert colors[-1] == libtcodpy.Color(255, 255, 255) def test_namegen_parse(): libtcodpy.namegen_parse('../data/namegen/jice_celtic.cfg') assert libtcodpy.namegen_generate('Celtic female') assert libtcodpy.namegen_get_sets() libtcodpy.namegen_destroy() def test_noise(): noise = libtcodpy.noise_new(1) libtcodpy.noise_set_type(noise, libtcodpy.NOISE_SIMPLEX) libtcodpy.noise_get(noise, [0]) libtcodpy.noise_get_fbm(noise, [0], 4) libtcodpy.noise_get_turbulence(noise, [0], 4) libtcodpy.noise_delete(noise) def test_random(): rand = libtcodpy.random_get_instance() rand = libtcodpy.random_new() libtcodpy.random_delete(rand) rand = libtcodpy.random_new_from_seed(42) libtcodpy.random_set_distribution(rand, libtcodpy.DISTRIBUTION_LINEAR) libtcodpy.random_get_int(rand, 0, 1) libtcodpy.random_get_int_mean(rand, 0, 1, 0) libtcodpy.random_get_float(rand, 0, 1) libtcodpy.random_get_double(rand, 0, 1) libtcodpy.random_get_float_mean(rand, 0, 1, 0) libtcodpy.random_get_double_mean(rand, 0, 1, 0) backup = libtcodpy.random_save(rand) libtcodpy.random_restore(rand, backup) libtcodpy.random_delete(rand) libtcodpy.random_delete(backup) def test_heightmap(): hmap = libtcodpy.heightmap_new(16, 16) repr(hmap) noise = libtcodpy.noise_new(2) # basic operations libtcodpy.heightmap_set_value(hmap, 0, 0, 1) libtcodpy.heightmap_add(hmap, 1) libtcodpy.heightmap_scale(hmap, 1) libtcodpy.heightmap_clear(hmap) libtcodpy.heightmap_clamp(hmap, 0, 0) libtcodpy.heightmap_copy(hmap, hmap) libtcodpy.heightmap_normalize(hmap) libtcodpy.heightmap_lerp_hm(hmap, hmap, hmap, 0) libtcodpy.heightmap_add_hm(hmap, hmap, hmap) libtcodpy.heightmap_multiply_hm(hmap, hmap, hmap) # modifying the heightmap libtcodpy.heightmap_add_hill(hmap, 0, 0, 4, 1) libtcodpy.heightmap_dig_hill(hmap, 0, 0, 4, 1) libtcodpy.heightmap_rain_erosion(hmap, 1, 1, 1) libtcodpy.heightmap_kernel_transform(hmap, 3, [-1, 1, 0], [0, 0, 0], [.33, .33, .33], 0, 1) libtcodpy.heightmap_add_voronoi(hmap, 10, 3, [1,3,5]) libtcodpy.heightmap_add_fbm(hmap, noise, 1, 1, 1, 1, 4, 1, 1) libtcodpy.heightmap_scale_fbm(hmap, noise, 1, 1, 1, 1, 4, 1, 1) libtcodpy.heightmap_dig_bezier(hmap, [0, 16, 16, 0], [0, 0, 16, 16], 1, 1, 1, 1) # read data libtcodpy.heightmap_get_value(hmap, 0, 0) libtcodpy.heightmap_get_interpolated_value(hmap, 0, 0) libtcodpy.heightmap_get_slope(hmap, 0, 0) libtcodpy.heightmap_get_normal(hmap, 0, 0, 0) libtcodpy.heightmap_count_cells(hmap, 0, 0) libtcodpy.heightmap_has_land_on_border(hmap, 0) libtcodpy.heightmap_get_minmax(hmap) libtcodpy.noise_delete(noise) libtcodpy.heightmap_delete(hmap) MAP = ( '############', '# ### #', '# ### #', '# ### ####', '## #### # ##', '## ####', '############', ) MAP_WIDTH = len(MAP[0]) MAP_HEIGHT = len(MAP) POINT_A = (2, 2) POINT_B = (9, 2) POINT_C = (9, 4) POINTS_AB = POINT_A + POINT_B # valid path POINTS_AC = POINT_A + POINT_C # invalid path @pytest.fixture() def map_(): map_ = libtcodpy.map_new(MAP_WIDTH, MAP_HEIGHT) for y, line in enumerate(MAP): for x, ch in enumerate(line): libtcodpy.map_set_properties(map_, x, y, ch == ' ', ch == ' ') yield map_ libtcodpy.map_delete(map_) @pytest.fixture() def path_callback(map_): def callback(ox, oy, dx, dy, user_data): if libtcodpy.map_is_walkable(map_, dx, dy): return 1 return 0 return callback def test_map_fov(map_): libtcodpy.map_compute_fov(map_, *POINT_A) def test_astar(map_): astar = libtcodpy.path_new_using_map(map_) assert not libtcodpy.path_compute(astar, *POINTS_AC) assert libtcodpy.path_size(astar) == 0 assert libtcodpy.path_compute(astar, *POINTS_AB) assert libtcodpy.path_get_origin(astar) == POINT_A assert libtcodpy.path_get_destination(astar) == POINT_B libtcodpy.path_reverse(astar) assert libtcodpy.path_get_origin(astar) == POINT_B assert libtcodpy.path_get_destination(astar) == POINT_A assert libtcodpy.path_size(astar) != 0 assert libtcodpy.path_size(astar) > 0 assert not libtcodpy.path_is_empty(astar) for i in range(libtcodpy.path_size(astar)): x, y = libtcodpy.path_get(astar, i) while (x, y) != (None, None): x, y = libtcodpy.path_walk(astar, False) libtcodpy.path_delete(astar) def test_astar_callback(map_, path_callback): astar = libtcodpy.path_new_using_function( libtcodpy.map_get_width(map_), libtcodpy.map_get_height(map_), path_callback, ) libtcodpy.path_compute(astar, *POINTS_AB) libtcodpy.path_delete(astar) def test_dijkstra(map_): path = libtcodpy.dijkstra_new(map_) libtcodpy.dijkstra_compute(path, *POINT_A) assert not libtcodpy.dijkstra_path_set(path, *POINT_C) assert libtcodpy.dijkstra_get_distance(path, *POINT_C) == -1 assert libtcodpy.dijkstra_path_set(path, *POINT_B) assert libtcodpy.dijkstra_size(path) assert not libtcodpy.dijkstra_is_empty(path) libtcodpy.dijkstra_reverse(path) for i in range(libtcodpy.dijkstra_size(path)): x, y = libtcodpy.dijkstra_get(path, i) while (x, y) != (None, None): x, y = libtcodpy.dijkstra_path_walk(path) libtcodpy.dijkstra_delete(path) def test_dijkstra_callback(map_, path_callback): path = libtcodpy.dijkstra_new_using_function( libtcodpy.map_get_width(map_), libtcodpy.map_get_height(map_), path_callback, ) libtcodpy.dijkstra_compute(path, *POINT_A) libtcodpy.dijkstra_delete(path) if __name__ == '__main__': pytest.main() libtcod-1.6.4+dfsg/samples/000077500000000000000000000000001321276576200155405ustar00rootroot00000000000000libtcod-1.6.4+dfsg/samples/apfviewer.cpp000066400000000000000000000015451321276576200202410ustar00rootroot00000000000000#include #include "libtcod.hpp" static float version=1.0f; int main(int argc, char *argv[]) { TCODConsole * rootcon = NULL; TCOD_key_t keyPress; TCOD_renderer_t renderer = TCOD_RENDERER_SDL; int row=50; int col=80; if ( argc < 2) { printf ("apfviewer ...\nversion %g\n",version); return 1; } TCODConsole::initRoot(col,row,"apfviewer",false,renderer ); TCODConsole con(1,1); for (int i=1; i < argc; i++) { if (strstr(argv[i],".asc")) con.loadAsc(argv[1]); else con.loadApf(argv[i]); delete TCODConsole::root; TCODConsole::root=NULL; TCODConsole::initRoot(con.getWidth(),con.getHeight(),argv[i],false,renderer ); TCODConsole::blit(&con,0,0,0,0,TCODConsole::root,0,0); TCODConsole::root->flush(); TCODSystem::waitForEvent(TCOD_EVENT_KEY_RELEASE|TCOD_EVENT_MOUSE_PRESS,NULL,NULL,true); } return 0; } libtcod-1.6.4+dfsg/samples/doctcod/000077500000000000000000000000001321276576200171575ustar00rootroot00000000000000libtcod-1.6.4+dfsg/samples/doctcod/doctcod.cpp000066400000000000000000001127631321276576200213140ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // This is libtcod doc generator // it parses .hpp files and use javadoc-like comments to build the doc // work-in-progress!! #include #include #include #include "libtcod.hpp" #ifdef TCOD_WINDOWS #define strdup _strdup #endif // index.html categories static const char *categs[] = {"", "Core","Base toolkits","Roguelike toolkits", "Howtos", NULL }; // a function parameter struct ParamData { char *name; char *desc; }; // data about a libtcod function struct FuncData { char *title;// function name char *desc; // general description char *cpp; // C++ function char *c; // C function char *cs; // C# function char *py; // python function char *lua; // lua function TCODList params; // parameters table char *cppEx; // C++ example char *cEx; // C example char *csEx; // C# example char *pyEx; // python example char *luaEx; // lua example FuncData() : title(NULL),desc(NULL),cpp(NULL),c(NULL),cs(NULL),py(NULL),lua(NULL), cppEx(NULL),cEx(NULL),csEx(NULL),pyEx(NULL),luaEx(NULL) {} }; // data about a documentation page struct PageData { // parsed data char *name; // page symbolic name char *title;// page title char *desc; // description on top of page char *fatherName; // symbolic name of father page if any char *filename; // .hpp file from which it comes char *categoryName; // category for level 0 pages TCODListfuncs; // functions in this page PageData() : name(NULL),title(NULL),desc(NULL), fatherName(NULL), filename(NULL),categoryName((char *)""),father(NULL),next(NULL),prev(NULL), fileOrder(0),order(0),numKids(0),pageNum(NULL), url(NULL), breadCrumb(NULL), prevLink((char *)""),nextLink((char*)""),colorTable(false) {} // computed data PageData *father; PageData *next; PageData *prev; int fileOrder; // page number in its hpp file int order; // page number in it's father int numKids; // number of sub pages inside this one char *pageNum; // 1.2 and so on... char *url; // page URL (ex.: 1.2.2.html) char *breadCrumb; char *prevLink; // link to prev page in breadcrumb char *nextLink; // link to next page in breadcrumb bool colorTable; }; struct Config { bool generateCpp; bool generateC; bool generatePy; bool generateCs; bool generateLua; }; Config config = {true,true,true,false,false}; TCODList pages; // root page corresponding to index.html PageData *root=NULL; // page currently parsed PageData *curPage=NULL; // function currently parsed FuncData *curFunc=NULL; // get an identifier at txt pos and put a strdup copy in result // returns the position after the identifier char *getIdentifier(char *txt, char **result) { while (isspace(*txt)) txt++; char *end=txt; while (!isspace(*end)) end++; *end=0; *result=strdup(txt); return end+1; } // get the end of line from txt and put a strdup copy in result // returns the position after the current line char *getLineEnd(char *txt, char **result) { while (isspace(*txt)) txt++; char *end=txt; while (*end && *end != '\n') end++; bool fileEnd = (*end == 0); *end=0; *result=strdup(txt); return fileEnd ? end : end+1; } // get the data from txt up to the next @ directive and put a strdup copy in result // returns the position at the next @ (or end of file) char *getParagraph(char *txt, char **result) { while (isspace(*txt)) txt++; char *end=txt; while (*end && *end != '@') end++; bool fileEnd = (*end == 0); *end=0; *result=strdup(txt); if ( ! fileEnd ) *end='@'; return end; } // get the data from txt up to the next @ directive and put a strdup copy in result // returns the position at the next @ (or end of file) char *getCodeParagraph(char *txt, char **result) { // for code, skip only up to the first \n to allow indentation detection while (isspace(*txt) && *txt != '\n') txt++; if ( *txt == '\n') txt++; char *end=txt; while (*end && *end != '@') end++; bool fileEnd = (*end == 0); *end=0; *result=strdup(txt); if ( ! fileEnd ) *end='@'; return end; } // check if the string starts with keyword bool startsWith(const char *txt, const char *keyword) { return strncmp(txt,keyword,strlen(keyword)) == 0; } // check if the string ends with keyword bool endsWith(const char *txt, const char *keyword) { return strncmp(txt+strlen(txt)-strlen(keyword),keyword,strlen(keyword)) == 0; } // print in the file, replace \n by
void printHtml(FILE *f, const char *txt) { bool intable=false; while (*txt) { if ( strncmp(txt,"",8) == 0 ) { intable=false; } if ( !intable && *txt == '\n' ) fprintf(f,"
"); else if ( *txt == '\r' ) {} // ignore else { fputc(*txt,f); } txt++; } } struct ColorModifier { const char *name; float satCoef; float valCoef; }; #define NB_COLOR_MOD 8 ColorModifier colorModifiers[NB_COLOR_MOD] = { {"desaturated", 0.5f,0.5f}, {"lightest",0.25f,1.0f}, {"lighter",0.35f,1.0f}, {"light",0.55f,1.0f}, {"",1.0f,1.0f}, {"dark",1.0f,0.75f}, {"darker",1.0f,0.5f}, {"darkest",1.0f,0.25f}, }; struct Color { char *name; TCODColor col; bool category; Color() : category(false) {} }; TCODList colors; int greyLevels[] = {223,191,159,127,95,63,31}; // generate the color table from parsed colors void printColorTable(FILE *f) { fprintf(f,"\n"); bool needHeader=true; int categ=0; for ( Color *col=colors.begin(); col!=colors.end(); col++) { if ( col->category ) { // a color category fprintf(f,"\n",col->name); needHeader=true; categ++; } else if ( categ == 1 ){ // computed colors if ( needHeader ) fprintf(f,"\n"); needHeader=false; fprintf(f,"",col->name); for (int cm =0; cm < NB_COLOR_MOD; cm++ ) { if ( colorModifiers[cm].name[0] != 0 ) col->name[0]=toupper(col->name[0]); float h,s,v; col->col.getHSV(&h,&s,&v); s *= colorModifiers[cm].satCoef; v *= colorModifiers[cm].valCoef; TCODColor modcol; modcol.setHSV(h,s,v); fprintf(f,"", colorModifiers[cm].name,col->name,modcol.r,modcol.g,modcol.b, modcol.r,modcol.g,modcol.b); col->name[0]=tolower(col->name[0]); } fprintf(f,"\n"); } else if (strcmp(col->name,"grey")==0 ) { // grey colors fprintf(f,"\n"); fprintf(f,"\n"); } else if ( strcmp(col->name,"sepia") == 0 ) { // sepia colors fprintf(f,""); } else { // miscellaneous colors fprintf(f,"\n", col->name, col->name,col->col.r,col->col.g,col->col.b, col->col.r,col->col.g,col->col.b); } } fprintf(f,"
%s
desaturatedlightestlighterlightnormaldarkdarkerdarkest
%s
 lightestlighterlightnormaldarkdarkerdarkest
grey 
sepia 
%s
"); } // print in the file, coloring syntax using the provided lexer void printSyntaxColored(FILE *f, TCODLex *lex) { char *pos=lex->getPos(); int indent=0; // detect first line indentation while ( isspace(*pos) ) { indent++; pos++; } int tok=lex->parse(); // fix indentation until real code begins bool lineBegin=true; while (tok != TCOD_LEX_ERROR && tok != TCOD_LEX_EOF ) { const char *spanClass=NULL; switch (tok) { case TCOD_LEX_SYMBOL : spanClass = "code-symbol"; break; case TCOD_LEX_KEYWORD : spanClass = "code-keyword"; break; case TCOD_LEX_STRING : spanClass = "code-string"; break; case TCOD_LEX_CHAR : spanClass = "code-character"; break; case TCOD_LEX_INTEGER : case TCOD_LEX_FLOAT : spanClass = "code-value"; break; case TCOD_LEX_COMMENT : spanClass = "code-comment"; break; case TCOD_LEX_IDEN : if ( startsWith(lex->getToken(),"TCOD_") && endsWith(lex->getToken(),"_t") ) spanClass = "code-tcod"; // tcod type else { char *ptr=(char *)lex->getToken(); bool isDefine=true; while (isDefine && *ptr) { if ( *ptr >= 'a' && *ptr <= 'z' ) isDefine=false; ptr++; } if ( isDefine ) spanClass="code-tcod"; // tcod constant } break; default : break; } if ( spanClass ) { fprintf(f, "",spanClass); } while ( pos != lex->getPos() ) { if ( *pos == '\r' ) {} else if (*pos == '\n' ) { fprintf(f,"
"); pos += indent; lineBegin=true; } else if ( lineBegin && *pos == '\t' ) { fprintf(f,"    "); } else if ( lineBegin && *pos == ' ' ) { fprintf(f," "); } else { fputc(*pos,f); if ( ! isspace(*pos) ) lineBegin=false; } pos++; } if ( spanClass ) { fprintf(f, "
"); } tok=lex->parse(); } if ( tok == TCOD_LEX_ERROR ) { printf ("ERROR while coloring syntax : %s in '%s'\n",TCOD_lex_get_last_error(),lex->getToken()); } } // print in the file, coloring syntax using C++ rules void printCppCode(FILE *f, const char *txt) { static const char *symbols[] = { "::","->","++","--","->*",".*","<<",">>","<=",">=","==","!=","&&","||","+=","-=","*=","/=","%=","&=","^=","|=","<<=",">>=","...", "(",")","[","]",".","+","-","!","~","*","&","|","%","/","<",">","=","^","?",":",";","{","}",",", NULL }; static const char *keywords[] = { "and","and_eq","asm","auto","bitand","bitor","bool","break","case","catch","char","class","compl","const","const_cast","continue", "default","delete","do","double","dynamic_cast","else","enum","explicit","export","extern","false","float","for","friend","goto", "if","inline","int","long","mutable","namespace","new","not","not_eq","operator","or","or_eq","private","protected","public", "register","reinterpret_cast","return","short","signed","sizeof","static","static_cast","struct","switch","template","this", "throw","true","try","typedef","typeid","typename","union","unsigned","using","virtual","void","volatile","wchar_t","while", "xor","xor_eq", "int8","int8_t","int16","int16_t","int32","int32_t","int64","int64_t", "uint8","uint8_t","uint16","uint16_t","uint32","uint32_t","uint64","uint64_t", NULL }; TCODLex lex(symbols,keywords,"//","/*","*/",NULL,"\"",TCOD_LEX_FLAG_NESTING_COMMENT|TCOD_LEX_FLAG_TOKENIZE_COMMENTS); lex.setDataBuffer((char *)txt); printSyntaxColored(f,&lex); } // print in the file, coloring syntax using C rules void printCCode(FILE *f, const char *txt) { static const char *symbols[] = { "->","++","--","<<",">>","<=",">=","==","!=","&&","||","*=","/=","+=","-=","%=","<<=",">>=","&=","^=","|=","...", "{","}","(",")","[","]",".","&","*","+","-","~","!","/","%","<",">","^","|","?",":","=",",",";", NULL }; static const char *keywords[] = { "auto","break","case","char","const","continue","default","do","double","else","enum","extern","float","for","goto","if","int", "long","register","return","short","signed","sizeof","static","struct","switch","typedef","union","unsigned","void","volatile", "while", "int8","int8_t","int16","int16_t","int32","int32_t","int64","int64_t","bool", "uint8","uint8_t","uint16","uint16_t","uint32","uint32_t","uint64","uint64_t", NULL }; TCODLex lex(symbols,keywords,"//","/*","*/",NULL,"\"",TCOD_LEX_FLAG_NESTING_COMMENT|TCOD_LEX_FLAG_TOKENIZE_COMMENTS); lex.setDataBuffer((char *)txt); printSyntaxColored(f,&lex); } // print in the file, coloring syntax using python rules void printPyCode(FILE *f, const char *txt) { static const char *symbols[] = { "**","&&","||","!=","<>","==","<=",">=","+=","-=","**=","*=","//=","/=","%=","|=","^=","<<=",">>=", "+","-","^","*","/","%","&","|","^","<",">","(",")","[","]","{","}",",",":",".","`","=",";","@", NULL }; static const char *keywords[] = { "and","as","assert","break","class","continue","def","del","elif","else","except","exec","finally","for", "from","global","if","import","in","is","lambda","not","or","pass","print","raise","return","try","while", "with","yield", "True","False", NULL }; TCODLex lex(symbols,keywords,"#","\"\"\"","\"\"\"",NULL,"\"\'",TCOD_LEX_FLAG_NESTING_COMMENT|TCOD_LEX_FLAG_TOKENIZE_COMMENTS); lex.setDataBuffer((char *)txt); printSyntaxColored(f,&lex); } // print in the file, coloring syntax using C# rules void printCSCode(FILE *f, const char *txt) { static const char *symbols[] = { "++","--","->","<<",">>","<=",">=","==","!=","&&","||","+=","-=","*=","/=","%=","&=","|=","^=","<<=",">>=","??", ".","(",")","[","]","{","}","+","-","!","~","&","*","/","%","<",">","^","|","?",":",",","=",";", NULL }; static const char *keywords[] = { "abstract","as","base","bool","break","byte","case","catch","char","checked","class","const","continue","decimal","default", "delegate","do","double","else","enum","event","explicit","extern","false","finally","fixed","float","for","foreach","goto", "implicit","in","int","interface","internal","is","lock","long","namespace","new","null","object","operator","out","override", "params","private","protected","public","readonly","ref","return","sbyte","sealed","short","sizeof","stackalloc","static", "string","struct","switch","this","throw","true","try","typeof","uint","ulong","unchecked","unsafe","ushort","using","virtual", "volatile","void","while", "get","partial","set","value","where","yield", NULL }; TCODLex lex(symbols,keywords,"//","/*","*/",NULL,"\"",TCOD_LEX_FLAG_NESTING_COMMENT|TCOD_LEX_FLAG_TOKENIZE_COMMENTS); lex.setDataBuffer((char *)txt); printSyntaxColored(f,&lex); } // print in the file, coloring syntax using Lua rules void printLuaCode(FILE *f, const char *txt) { static const char *symbols[] = { "==","~=","<=",">=","...","..", "+","-","/","*","%","^","<",">",",","(",")","#","{","}","[","]","=",";",":",".", NULL }; static const char *keywords[] = { "and","break","do","else","elseif", "end", "false", "for", "function", "if", "in", "local", "nil", "not", "or", "repeat", "return", "then", "true", "until", "while", NULL }; TCODLex lex(symbols,keywords,"--","--[[","]]",NULL,"\"\'",TCOD_LEX_FLAG_NESTING_COMMENT|TCOD_LEX_FLAG_TOKENIZE_COMMENTS); lex.setDataBuffer((char *)txt); printSyntaxColored(f,&lex); } // get a page by its name or NULL if it doesn't exist PageData *getPage(const char *name) { for (PageData **it=pages.begin();it!=pages.end();it++) { if (strcmp((*it)->name,name)==0) return *it; } return NULL; } // find the previous page of same level (NULL if none) PageData *getPrev(PageData *page) { for (PageData **it=pages.begin();it!=pages.end();it++) { if ( (*it)->father == page->father && (*it)->order == page->order-1 ) return *it; } return NULL; } // find the next page of same level (NULL if none) PageData *getNext(PageData *page) { for (PageData **it=pages.begin();it!=pages.end();it++) { if ( (*it)->father == page->father && (*it)->order == page->order+1 ) return *it; } return NULL; } // load a text file into memory. get rid of \r char *loadTextFile(const char *filename) { // load the file into memory (should probably use mmap instead that crap...) struct stat _st; FILE *f = fopen( filename, "r" ); if ( f == NULL ) { printf("WARN : cannot open '%s'\n", filename); return NULL; } if ( stat( filename, &_st ) == -1 ) { fclose(f); printf("WARN : cannot stat '%s'\n", filename ); return NULL; } char *buf = (char*)calloc(sizeof(char),(_st.st_size + 1)); char *ptr=buf; // can't rely on size to read because of MS/DOS dumb CR/LF handling while ( fgets(ptr, _st.st_size,f ) ) { ptr += strlen(ptr); } fclose(f); // remove \r ptr = buf; while (*ptr) { if ( *ptr == '\r') { char *ptr2=ptr; while ( *ptr2 ) { *ptr2 = *(ptr2+1); ptr2++; } } ptr++; } return buf; } // parse a .hpp file and generate corresponding PageData void parseFile(char *filename) { printf ("INFO : parsing file %s\n",filename); char *buf=loadTextFile(filename); if ( ! buf ) return; // now scan javadocs int fileOrder=1; char *ptr = strstr(buf,"/**"); while (ptr) { char *end = strstr(ptr,"*/"); if ( end ) { // parse the javadoc *end=0; char *directive = strchr(ptr,'@'); while ( directive ) { if ( startsWith(directive,"@PageName") ) { char *pageName=NULL; directive = getIdentifier(directive+sizeof("@PageName"),&pageName); curPage=getPage(pageName); curFunc=NULL; if(!curPage) { // non existing page. create a new one curPage=new PageData(); pages.push(curPage); curPage->filename = strdup(filename); curPage->fileOrder=fileOrder++; curPage->name=pageName; curFunc=NULL; } } else if ( startsWith(directive,"@PageTitle") ) { directive = getLineEnd(directive+sizeof("@PageTitle"),&curPage->title); } else if ( startsWith(directive,"@PageDesc") ) { directive = getParagraph(directive+sizeof("@PageDesc"),&curPage->desc); } else if ( startsWith(directive,"@PageFather") ) { directive = getIdentifier(directive+sizeof("@PageFather"),&curPage->fatherName); if ( strcmp(curPage->fatherName,curPage->name) == 0 ) { printf ("ERROR : file %s : page %s is its own father\n", filename, curPage->name); exit(1); } } else if ( startsWith(directive,"@PageCategory") ) { directive = getLineEnd(directive+sizeof("@PageCategory"),&curPage->categoryName); } else if ( startsWith(directive,"@FuncTitle") ) { curFunc=new FuncData(); curPage->funcs.push(curFunc); directive = getLineEnd(directive+sizeof("@FuncTitle"),&curFunc->title); } else if ( startsWith(directive,"@ColorTable") ) { directive += sizeof("@ColorTable"); curPage->colorTable=true; } else if ( startsWith(directive,"@ColorCategory") ) { Color *catCol = new Color(); directive=getLineEnd(directive+sizeof("@ColorCategory"),&catCol->name); catCol->category=true; colors.push(*catCol); } else if ( startsWith(directive,"@Color") ) { Color *col = new Color(); int colr, colg, colb; directive=getIdentifier(directive+sizeof("@Color"),&col->name); sscanf(directive,"%d,%d,%d",&colr, &colg, &colb); col->col.r = (uint8_t)colr; col->col.g = (uint8_t)colg; col->col.b = (uint8_t)colb; colors.push(*col); while (! isspace(*directive)) directive++; } else if ( startsWith(directive,"@FuncDesc") ) { if (! curFunc ) { curFunc=new FuncData(); curPage->funcs.push(curFunc); } directive = getParagraph(directive+sizeof("@FuncDesc"),&curFunc->desc); } else if ( startsWith(directive,"@CppEx") ) { if (! curFunc ) { curFunc=new FuncData(); curPage->funcs.push(curFunc); } directive = getCodeParagraph(directive+sizeof("@CppEx")-1,&curFunc->cppEx); } else if ( startsWith(directive,"@C#Ex") ) { if (! curFunc ) { curFunc=new FuncData(); curPage->funcs.push(curFunc); } directive = getCodeParagraph(directive+sizeof("@C#Ex")-1,&curFunc->csEx); } else if ( startsWith(directive,"@CEx") ) { if (! curFunc ) { curFunc=new FuncData(); curPage->funcs.push(curFunc); } directive = getCodeParagraph(directive+sizeof("@CEx")-1,&curFunc->cEx); } else if ( startsWith(directive,"@PyEx") ) { if (! curFunc ) { curFunc=new FuncData(); curPage->funcs.push(curFunc); } directive = getCodeParagraph(directive+sizeof("@PyEx")-1,&curFunc->pyEx); } else if ( startsWith(directive,"@LuaEx") ) { if (! curFunc ) { curFunc=new FuncData(); curPage->funcs.push(curFunc); } directive = getCodeParagraph(directive+sizeof("@LuaEx")-1,&curFunc->luaEx); } else if ( startsWith(directive,"@Cpp") ) { if (! curFunc ) { curFunc=new FuncData(); curPage->funcs.push(curFunc); } directive = getCodeParagraph(directive+sizeof("@Cpp")-1,&curFunc->cpp); } else if ( startsWith(directive,"@C#") ) { if (! curFunc ) { curFunc=new FuncData(); curPage->funcs.push(curFunc); } directive = getCodeParagraph(directive+sizeof("@C#")-1,&curFunc->cs); } else if ( startsWith(directive,"@C") ) { if (! curFunc ) { curFunc=new FuncData(); curPage->funcs.push(curFunc); } directive = getCodeParagraph(directive+sizeof("@C")-1,&curFunc->c); } else if ( startsWith(directive,"@Py") ) { if (! curFunc ) { curFunc=new FuncData(); curPage->funcs.push(curFunc); } directive = getCodeParagraph(directive+sizeof("@Py")-1,&curFunc->py); } else if ( startsWith(directive,"@Lua") ) { if (! curFunc ) { curFunc=new FuncData(); curPage->funcs.push(curFunc); } directive = getCodeParagraph(directive+sizeof("@Lua")-1,&curFunc->lua); } else if ( startsWith(directive,"@Param") ) { ParamData *param=new ParamData(); curFunc->params.push(param); directive = getIdentifier(directive+sizeof("@Param"),¶m->name); directive = getParagraph(directive,¶m->desc); } else { char *tmp; directive = getIdentifier(directive,&tmp); printf ("WARN unknown directive '%s'\n",tmp); free(tmp); } directive = strchr(directive,'@'); } ptr=strstr(end+2,"/**"); } else ptr=NULL; } } // computes the page tree and auto-numbers pages void buildTree() { // get the list of root (level 0) pages TCODListrootPages; for (PageData **it=pages.begin();it!=pages.end();it++) { // page requires at least a @PageName and @PageTitle if (! (*it)->name ) { printf ("ERROR : page #%d (%s) in %s has no @PageName\n", (*it)->fileOrder,(*it)->name ? (*it)->name : "null", (*it)->filename); it=pages.remove(it); continue; } if (! (*it)->title ) { printf ("ERROR : page #%d (%s) in %s has no @PageTitle\n", (*it)->fileOrder,(*it)->name ? (*it)->name : "null",(*it)->filename); it=pages.remove(it); continue; } if ( (*it)->fatherName == NULL ) rootPages.push(*it); } // first, order the level 0 pages according to their category int categId=0; while ( categs[categId] ) { for (PageData **it=pages.begin();it!=pages.end();it++) { if ( (*it)->fatherName == NULL && strcmp((*it)->categoryName,categs[categId]) == 0 ) { // new root page root->numKids++; (*it)->father=root; (*it)->order=root->numKids; char tmp[1024]; sprintf(tmp,"%d",(*it)->order); (*it)->pageNum=strdup(tmp); sprintf(tmp,"doc/html2/%s.html",(*it)->name); (*it)->url=strdup(tmp); sprintf(tmp,"Index > %s. %s", (*it)->name,(*it)->pageNum,(*it)->title); (*it)->breadCrumb=strdup(tmp); rootPages.remove(*it); } } categId++; } // pages with unknown categories for ( PageData **it=rootPages.begin(); it != rootPages.end(); it++) { printf ("ERROR : unknown category '%s' in page '%s'\n",(*it)->categoryName,(*it)->name); pages.remove(*it); } // build the subpages tree for (PageData **it=pages.begin();it!=pages.end();it++) { if ( (*it)->fatherName != NULL ) { // sub-page. find its daddy and order (*it)->father=getPage((*it)->fatherName); if ( ! (*it)->father ) { printf ("ERROR : unknown father '%s' for page '%s'\n", (*it)->fatherName,(*it)->name); it=pages.remove(it); continue; } (*it)->father->numKids++; (*it)->order=(*it)->father->numKids; } } // now compute sub-page numbers TCODList hierarchy; bool missing=true; while ( missing ) { missing=false; for (PageData **it=pages.begin();it!=pages.end();it++) { if ((*it)->pageNum == NULL ) { PageData *page=*it; if ( page->father->pageNum == NULL ) { missing=true; } else { char tmp[256]; sprintf(tmp,"%s.%d", page->father->pageNum,page->order); page->pageNum = strdup(tmp); sprintf(tmp,"doc/html2/%s.html",page->name); page->url=strdup(tmp); } } } } // now compute prev/next links and breadcrumbs for sub pages for (PageData **it=pages.begin();it!=pages.end();it++) { PageData *page=*it; page->prev=getPrev(page); // prev link if ( page->prev ) { char tmp[1024]; sprintf (tmp, "%s. %s", page->prev->name,page->prev->pageNum,page->prev->title); page->prevLink=strdup(tmp); } // next link page->next=getNext(page); if ( page->next ) { char tmp[1024]; sprintf (tmp, "%s%s. %s", page->prev ? "| " : "", page->next->name,page->next->pageNum,page->next->title); page->nextLink=strdup(tmp); } // breadCrumb if (! page->breadCrumb ) { char tmp[1024]; TCODList hierarchy; PageData *curPage=page; while ( curPage ) { hierarchy.push(curPage); curPage=curPage->father; } char *ptr=tmp; ptr[0]=0; while ( ! hierarchy.isEmpty() ) { curPage=hierarchy.pop(); if ( curPage == root ) { sprintf(ptr, "%s", curPage->name,curPage->title); } else { sprintf(ptr, " > %s. %s", curPage->name,curPage->pageNum,curPage->title); } ptr += strlen(ptr); } page->breadCrumb =strdup(tmp); } } } // return the subpage # kidNum PageData *getKidByNum(PageData *father, int kidNum) { for (PageData **it=pages.begin(); it != pages.end(); it++) { if ( (*it)->father == father && (*it)->order == kidNum ) { return *it; } } return NULL; } // print subpage TOC for a standard (not index.htlm) page void printStandardPageToc(FILE *f,PageData *page) { if ( page->numKids > 0 ) { fprintf(f,"
    "); for (int kidId=1;kidId <= page->numKids; kidId++) { // find the kid # kidId PageData *kid = getKidByNum(page,kidId); if ( kid ) { if ( kid->numKids > 0 ) { // level 2 fprintf (f,"
  • %s. %s
      \n", page==root ? "html2/":"", kid->name,kid->pageNum,kid->title); int kidKidId=1; while (kidKidId <= kid->numKids ) { PageData *kidKid=NULL; // find the kid # kidKidId of kidId kidKid=getKidByNum(kid,kidKidId); if ( kidKid ) { fprintf(f,"
    • %s. %s
    • \n", page==root ? "html2/":"", kidKid->name,kidKid->pageNum,kidKid->title); } kidKidId++; } fprintf(f,"
  • \n"); } else { fprintf(f,"
  • %s. %s
  • \n", page==root ? "html2/":"", kid->name,kid->pageNum,kid->title); } } } fprintf(f,"
\n"); } } // print index.html TOC void printRootPageToc(FILE *f,PageData *page) { int categId=0; fprintf(f,"
    "); while ( categs[categId] ) { if ( categId > 0 ) fprintf(f, "
  • %s
  • \n",categs[categId]); for ( int kidId=1;kidId <= page->numKids; kidId++ ) { PageData *kid = getKidByNum(page,kidId); if ( kid && strcmp(kid->categoryName,categs[categId]) ==0 ) { if ( kid->numKids > 0 ) { // level 2 fprintf (f,"
  • %s. %s
      \n", page==root ? "html2/":"", kid->name,kid->pageNum,kid->title); int kidKidId=1; while (kidKidId <= kid->numKids ) { PageData *kidKid=getKidByNum(kid,kidKidId); if ( kidKid ) { fprintf(f,"
    • %s. %s
    • \n", page==root ? "html2/":"", kidKid->name,kidKid->pageNum,kidKid->title); } kidKidId++; } fprintf(f,"
  • \n"); } else { fprintf(f,"
  • %s. %s
  • \n", page==root ? "html2/":"", kid->name,kid->pageNum,kid->title); } } } categId++; } fprintf(f,"
\n"); } void printLanguageFilterForm(FILE *f, const char *langCode, const char *langName, bool onoff) { fprintf(f,"", langCode,langCode,langCode, onoff ? "checked='checked'" : "", onoff ? "":"disabled='disabled'", onoff ? "" : "class='disabled'", langCode,langName); } // generate a .html file for one page void genPageDocFromTemplate(PageData *page) { char *pageTpl=loadTextFile("samples/doctcod/page.tpl"); if (! pageTpl) return; FILE *f = fopen(page->url,"wt"); while (*pageTpl) { if ( strncmp(pageTpl,"${TITLE}",8) == 0 ) { // navigator window's title fprintf(f,page->title); pageTpl+=8; } else if ( strncmp(pageTpl,"${SCRIPT}",9) == 0 ) { // javascript file (not the same for index.html and other pages) if (page == root) fprintf(f,"js/doctcod.js"); else fprintf(f,"../js/doctcod.js"); pageTpl+=9; } else if ( strncmp(pageTpl,"${STYLESHEET}",13) == 0 ) { // css file (not the same for index.html and other pages) if (page == root) fprintf(f,"css/style.css"); else fprintf(f,"../css/style.css"); pageTpl+=13; } else if ( strncmp(pageTpl,"${LOCATION}",11) == 0 ) { // breadcrumb fprintf(f,page->breadCrumb); pageTpl+=11; } else if ( strncmp(pageTpl,"${FILTER_FORM}",14) == 0 ) { printLanguageFilterForm(f,"c","C",config.generateC); printLanguageFilterForm(f,"cpp","C++",config.generateCpp); printLanguageFilterForm(f,"py","Py",config.generatePy); printLanguageFilterForm(f,"lua","Lua",config.generateLua); printLanguageFilterForm(f,"cs","C#",config.generateCs); pageTpl+=14; } else if ( strncmp(pageTpl,"${PREV_LINK}",12) == 0 ) { // prev page link fprintf(f,page->prevLink); pageTpl+=12; } else if ( strncmp(pageTpl,"${NEXT_LINK}",12) == 0 ) { // next page link fprintf(f,page->nextLink); pageTpl+=12; } else if ( strncmp(pageTpl,"${PAGE_TITLE}",13) == 0 ) { // page title if ( page == root ) fprintf(f,page->desc); else fprintf(f,"%s. %s",page->pageNum, page->title); pageTpl+=13; } else if ( strncmp(pageTpl,"${PAGE_CONTENT}",15) == 0 ) { pageTpl+=15; // sub pages toc if ( page == root ) printRootPageToc(f,page); else printStandardPageToc(f,page); // functions toc if ( page->funcs.size() > 1 ) { fprintf(f,"
    \n"); int i=0; for ( FuncData **fit=page->funcs.begin(); fit != page->funcs.end(); fit++,i++) { FuncData *funcData=*fit; if ( funcData->title ) { fprintf(f, "
  • %s
  • ", i,funcData->title); } } fprintf(f,"
\n"); } // page description if ( page != root && page->desc ) { fprintf(f,"

"); printHtml(f,page->desc); fprintf(f,"

\n"); if ( page->colorTable ) printColorTable(f); } // functions int i=0; for ( FuncData **fit=page->funcs.begin(); fit != page->funcs.end(); fit++,i++) { FuncData *funcData=*fit; // title and description fprintf(f,"",i); if (funcData->title) fprintf(f,"

%s

\n",funcData->title); if (funcData->desc) { fprintf(f,"

"); printHtml(f,funcData->desc); fprintf(f,"

\n"); } // functions for each language fprintf(f,"
"); if (config.generateCpp && funcData->cpp) { fprintf(f,"

"); printCppCode(f,funcData->cpp); fprintf(f,"

\n"); } if (config.generateC && funcData->c) { fprintf(f,"

"); printCCode(f,funcData->c); fprintf(f,"

\n"); } if (config.generatePy && funcData->py) { fprintf(f,"

"); printPyCode(f,funcData->py); fprintf(f,"

\n"); } if (config.generateCs && funcData->cs) { fprintf(f,"

"); printCSCode(f,funcData->cs); fprintf(f,"

\n"); } if (config.generateLua && funcData->lua) { fprintf(f,"

"); printLuaCode(f,funcData->lua); fprintf(f,"

\n"); } fprintf(f,"
\n"); // parameters table if ( !funcData->params.isEmpty()) { fprintf(f,""); bool hilite=true; for ( ParamData **pit = funcData->params.begin(); pit != funcData->params.end(); pit++) { if ( hilite ) fprintf(f,""); else fprintf(f,""); fprintf(f,"\n"); hilite=!hilite; } fprintf(f,"
ParameterDescription
%s",(*pit)->name); printHtml(f,(*pit)->desc); fprintf(f,"
"); } // examples if ( funcData->cppEx || funcData->cEx || funcData->pyEx ) { fprintf(f,"
Example:
\n"); if (config.generateCpp && funcData->cppEx) { fprintf(f,"

"); printCppCode(f,funcData->cppEx); fprintf(f,"

\n"); } if (config.generateC && funcData->cEx) { fprintf(f,"

"); printCCode(f,funcData->cEx); fprintf(f,"

\n"); } if (config.generatePy && funcData->pyEx) { fprintf(f,"

"); printPyCode(f,funcData->pyEx); fprintf(f,"

\n"); } if (config.generateCs && funcData->csEx) { fprintf(f,"

"); printCSCode(f,funcData->csEx); fprintf(f,"

\n"); } if (config.generateLua && funcData->luaEx) { fprintf(f,"

"); printLuaCode(f,funcData->luaEx); fprintf(f,"

\n"); } fprintf(f,"

\n"); } } } else { fputc(*pageTpl,f); pageTpl++; } } fclose(f); } // export to HTML void genDoc() { // generates the doc for each page for (PageData **it=pages.begin();it!=pages.end();it++) { printf ("Generating %s - %s...\n",(*it)->pageNum,(*it)->title); genPageDocFromTemplate(*it); } genPageDocFromTemplate(root); } // main func int main(int argc, char *argv[]) { // parse command line arguments // -c -cpp -py -cs -lua : enable only the languages if ( argc > 1 ) { config.generateCpp=false; config.generateC=false; config.generatePy=false; config.generateCs=false; config.generateLua=false; } for (int pnum=1; pnum < argc; pnum++) { if ( strcmp(argv[pnum],"-c") == 0 ) config.generateC=true; else if ( strcmp(argv[pnum],"-cpp") == 0 ) config.generateCpp=true; else if ( strcmp(argv[pnum],"-cs") == 0 ) config.generateCs=true; else if ( strcmp(argv[pnum],"-py") == 0 ) config.generatePy=true; else if ( strcmp(argv[pnum],"-lua") == 0 ) config.generateLua=true; } TCODList files=TCODSystem::getDirectoryContent("include", "*.hpp"); // hardcoded index page char tmp[128]; root = new PageData(); root->name=(char *)"index2"; root->title=(char *)"Index"; root->pageNum=(char *)""; root->breadCrumb=(char *)"Index"; root->url=(char *)"doc/index2.html"; sprintf(tmp,"The Doryen Library v%s - table of contents",TCOD_STRVERSION); root->desc=strdup(tmp); // parse the *.hpp files for ( char **it=files.begin(); it != files.end(); it++) { char tmp[128]; sprintf(tmp,"include/%s",*it); parseFile(tmp); } // computations buildTree(); // html export genDoc(); } libtcod-1.6.4+dfsg/samples/doctcod/page.tpl000066400000000000000000000034371321276576200206230ustar00rootroot00000000000000 libtcod documentation | ${TITLE}

libtcoddocumentation

${FILTER_FORM}

${PAGE_TITLE}

${PAGE_CONTENT}
libtcod-1.6.4+dfsg/samples/frost/000077500000000000000000000000001321276576200166755ustar00rootroot00000000000000libtcod-1.6.4+dfsg/samples/frost/frost.cpp000066400000000000000000000123401321276576200205360ustar00rootroot00000000000000#include #include #include "libtcod.hpp" #define _SDL_main_h #include "libtcod_int.h" TCODColor frostCol[256]; int keys[4]={0,60,200,255}; TCODColor keyCols[4]={TCODColor::black,TCODColor::darkerBlue,TCODColor::lighterBlue,TCODColor::lightestBlue}; #define GROW 5000.0f #define ANGLE_DELAY 0.2f #define FROST_LEVEL 0.8f #define SMOOTH 0.3f #define PIX_PER_FRAME 6 #define RANGE 10 struct Frost; class FrostManager { public : FrostManager(int w, int h); ~FrostManager(); void addFrost(int x, int y); void update(float elapsed); void render(); void clear(); inline float getValue(int cx, int cy) { TCOD_IFNOT(cx+cy*w >= 0 && cx+cy*w < w*h) return 0.0f; return grid[cx+cy*w]; } inline void setValue(int cx, int cy,float v) { TCOD_IFNOT(cx+cy*w >= 0 && cx+cy*w < w*h) return; grid[cx+cy*w]=v; } protected : friend struct Frost; TCODList list; float *grid; TCODImage *img; int w,h; }; struct Frost { int x,y,bestx,besty,rx,ry; int border; FrostManager *manager; float timer; float ra; float rr; Frost(int x, int y, FrostManager *manager); inline float getValue(int cx, int cy) { return manager->getValue(x-RANGE+cx,y-RANGE+cy); } inline void setValue(int cx, int cy,float v) { manager->setValue(x-RANGE+cx,y-RANGE+cy,v); } bool update(float elapsed); void render(TCODImage *img); }; FrostManager::FrostManager(int w, int h) : w(w),h(h) { grid = new float[w*h]; img=new TCODImage(w,h); clear(); } FrostManager::~FrostManager() { delete [] grid; delete img; } void FrostManager::addFrost(int x, int y) { list.push(new Frost(x,y,this)); setValue(x,y,1.0f); } void FrostManager::clear() { img->clear(TCODColor::black); memset(grid,0,sizeof(float)*w*h); } void FrostManager::update(float elapsed) { TCODListtoRemove; for (Frost **it=list.begin();it!=list.end();it++) { if (!(*it)->update(elapsed)) toRemove.push(*it); } for (Frost **it=toRemove.begin();it!=toRemove.end();it++) { list.removeFast(*it); } toRemove.clearAndDelete(); } void FrostManager::render() { for (Frost **it=list.begin();it!=list.end();it++) { (*it)->render(img); } img->blit2x(TCODConsole::root,0,0); } Frost::Frost(int x, int y, FrostManager *manager) :x(x),y(y),manager(manager) { border=0; timer=0.0f; } bool Frost::update(float elapsed) { for (int i=PIX_PER_FRAME;i> 0; i--) { timer -= elapsed; if ( timer <= 0 ) { // find a new random frost direction ra = TCODRandom::getInstance()->getFloat(0.0f,2*3.1415926f); rr = TCODRandom::getInstance()->getFloat(0,2*RANGE); timer=ANGLE_DELAY; rx=(int)(RANGE + rr*cosf(ra)); ry=(int)(RANGE + rr*sinf(ra)); int minDist=100000; // find closest frost pixel for (int cx=1; cx < 2*RANGE; cx++) { if ( (unsigned)(x-RANGE+cx) < (unsigned)manager->w ) { for (int cy=1; cy < 2*RANGE; cy++) { if ( (unsigned)(y-RANGE+cy) < (unsigned)manager->h ) { float f=getValue(cx,cy); if ( f > FROST_LEVEL ) { int dist=(cx-rx)*(cx-rx)+(cy-ry)*(cy-ry); if ( dist < minDist ) { minDist=dist; bestx=cx; besty=cy; } } } } } } } // smoothing for (int cx=0; cx < 2*RANGE+1; cx++) { if ( x-RANGE+cx < manager->w-1 && x-RANGE+cx > 0 ) { for (int cy=0; cy < 2*RANGE+1; cy++) { if ( y-RANGE+cy < manager->h-1 && y-RANGE+cy > 0 ) { if ( getValue(cx,cy)< 1.0f) { float f=getValue(cx,cy); float oldf=f; f=MAX(f,getValue(cx+1,cy)); f=MAX(f,getValue(cx-1,cy)); f=MAX(f,getValue(cx,cy+1)); f=MAX(f,getValue(cx,cy-1)); setValue(cx,cy,oldf+(f-oldf)*SMOOTH*elapsed); } } } } } int curx=bestx; int cury=besty; // frosting TCODLine::init(curx,cury,rx,ry); TCODLine::step(&curx,&cury); if ((unsigned)(x-RANGE+curx) < (unsigned)manager->w && (unsigned)(y-RANGE+cury) < (unsigned)manager->h) { float f=getValue(curx,cury); f+=GROW*elapsed; f=MIN(1.0f,f); setValue(curx,cury,f); if ( f==1.0f ) { bestx=curx;besty=cury; if ( bestx==rx && besty==ry ) timer=0.0f; timer=0.0f; if ( curx == 0 || curx == 2*RANGE || cury ==0 || cury == 2*RANGE ) { border++; if ( border==20 ) return false; } } } else timer=0.0f; } return true; } void Frost::render(TCODImage *img) { int w,h; img->getSize(&w,&h); for (int cx=x-RANGE; cx <= x+RANGE;cx++) { if ( (unsigned)cx < (unsigned)w ) { for (int cy=y-RANGE; cy <= y+RANGE;cy++) { if ( (unsigned)cy < (unsigned)h ) { float f=getValue(cx - (x-RANGE), cy-(y-RANGE)); int idx=(int)(f*255); idx=MIN(255,idx); img->putPixel(cx,cy,frostCol[idx]); } } } } } int main(int argc, char** argv) { TCODConsole::initRoot(80, 50, "frost test", false); TCOD_mouse_t mouse; TCOD_key_t key; TCODSystem::setFps(25); TCODColor::genMap(frostCol,sizeof(keys)/sizeof(int),keyCols,keys); FrostManager frostManager(160,100); while (! TCODConsole::isWindowClosed()) { frostManager.render(); TCODConsole::flush(); TCODSystem::checkForEvent(TCOD_EVENT_KEY_RELEASE|TCOD_EVENT_MOUSE,&key,&mouse); if ( key.vk == TCODK_BACKSPACE ) frostManager.clear(); if ( mouse.lbutton ) { frostManager.addFrost(mouse.cx*2,mouse.cy*2); } frostManager.update(TCODSystem::getLastFrameLength()); } return 0; } libtcod-1.6.4+dfsg/samples/hmtool/000077500000000000000000000000001321276576200170425ustar00rootroot00000000000000libtcod-1.6.4+dfsg/samples/hmtool/README.txt000066400000000000000000000005631321276576200205440ustar00rootroot00000000000000libtcod height map tool Actually this is currently more a curiosity than a real useful tool. It allows you to tweak a heightmap by hand and generate the corresponding C,C++ or Python code. The heightmap tool source code is public domain. Do whatever you want with it. NB : this tool has not been upgraded to the latest libtcod API so the generated code won't compile. libtcod-1.6.4+dfsg/samples/hmtool/hmtool.cpp000066400000000000000000000400621321276576200210520ustar00rootroot00000000000000#include #include #include #include "libtcod.hpp" #include "gui/gui.hpp" #include "operation.hpp" TCODHeightMap *hm=NULL, *hmold=NULL; TCODNoise *noise= NULL; TCODRandom *rnd=NULL, *backupRnd=NULL; TCODConsole *guicon=NULL; bool greyscale=false; bool slope=false; bool normal=false; bool isNormalized=true; bool oldNormalized=true; char msg[512]=""; float msgDelay=0.0f; float hillRadius=0.1f; float hillVariation=0.5f; float addFbmDelta=0.0f; float scaleFbmDelta=0.0f; uint32_t seed=0xdeadbeef; float sandHeight=0.12f; float grassHeight=0.315f; float snowHeight=0.785f; char landMassTxt[128]=""; char minZTxt[128]=""; char maxZTxt[128]=""; char seedTxt[128]=""; float mapmin=0.0f,mapmax=0.0f; float oldmapmin=0.0f,oldmapmax=0.0f; // ui ToolBar *params=NULL; ToolBar *history=NULL; ToolBar *colorMapGui=NULL; float voronoiCoef[2] = { -1.0f,1.0f }; /* light 3x3 smoothing kernel : 1 2 1 2 20 2 1 2 1 */ int smoothKernelSize=9; int smoothKernelDx[9]={ -1,0,1,-1,0,1,-1,0,1 }; int smoothKernelDy[9]={ -1,-1,-1,0,0,0,1,1,1 }; float smoothKernelWeight[9]={ 1,2,1,2,20,2,1,2,1 }; TCODColor mapGradient[256]; #define MAX_COLOR_KEY 10 // TCOD's land color map static int keyIndex[MAX_COLOR_KEY] = {0, (int)(sandHeight*255), (int)(sandHeight*255)+4, (int)(grassHeight*255), (int)(grassHeight*255)+10, (int)(snowHeight*255), (int)(snowHeight*255)+10, 255 }; static TCODColor keyColor[MAX_COLOR_KEY]= { TCODColor(0,0,50), // deep water TCODColor(30,30,170), // water-sand transition TCODColor(114,150,71),// sand TCODColor(80,120,10),// sand-grass transition TCODColor(17,109,7), // grass TCODColor(120,220,120), // grass-snow transisiton TCODColor(208,208,239), // snow TCODColor(255,255,255) }; static Image *keyImages[MAX_COLOR_KEY]; static int nbColorKeys=8; void initColors() { TCODColor::genMap(mapGradient,nbColorKeys,keyColor,keyIndex); } void render() { static TCODHeightMap backup(HM_WIDTH,HM_HEIGHT); isNormalized=true; TCODConsole::root->setDefaultBackground(TCODColor::black); TCODConsole::root->setDefaultForeground(TCODColor::white); TCODConsole::root->clear(); backup.copy(hm); mapmin=1E8f; mapmax=-1E8f; for (int i=0; i < HM_WIDTH*HM_HEIGHT; i++) { if ( hm->values[i] < 0.0f || hm->values[i] > 1.0f ) { isNormalized=false; } if ( hm->values[i] < mapmin ) mapmin=hm->values[i]; if ( hm->values[i] > mapmax ) mapmax=hm->values[i]; } if (! isNormalized ) backup.normalize(); // render the TCODHeightMap for (int x=0; x < HM_WIDTH; x ++ ) { for (int y=0;y < HM_HEIGHT; y++ ) { float z = backup.getValue(x,y); uint8_t val=(uint8_t)(z*255); if ( slope ) { // render the slope map z = CLAMP(0.0f,1.0f,hm->getSlope(x,y)*10.0f); val = (uint8_t)(z*255); TCODColor c(val,val,val); TCODConsole::root->setCharBackground(x,y,c); } else if ( greyscale ) { // render the greyscale heightmap TCODColor c(val,val,val); TCODConsole::root->setCharBackground(x,y,c); } else if ( normal) { // render the normal map float n[3]; hm->getNormal((float)x,(float)y,n,mapmin); uint8_t r = (uint8_t)((n[0]*0.5f+0.5f)*255); uint8_t g = (uint8_t)((n[1]*0.5f+0.5f)*255); uint8_t b = (uint8_t)((n[2]*0.5f+0.5f)*255); TCODColor c(r,g,b); TCODConsole::root->setCharBackground(x,y,c); } else { // render the colored heightmap TCODConsole::root->setCharBackground(x,y,mapGradient[val]); } } } sprintf(minZTxt,"min z : %.2f",mapmin); sprintf(maxZTxt,"max z : %.2f",mapmax); sprintf(seedTxt,"seed : %X",seed); float landProportion=100.0f - 100.0f*backup.countCells(0.0f,sandHeight) / (hm->w*hm->h); sprintf(landMassTxt,"landMass : %d %%%%",(int)landProportion); if ( ! isNormalized ) TCODConsole::root->printEx(HM_WIDTH/2,HM_HEIGHT-1,TCOD_BKGND_NONE,TCOD_CENTER,"the map is not normalized !"); // message msgDelay-=TCODSystem::getLastFrameLength(); if ( msg[0] != 0 && msgDelay > 0.0f ) { int h=TCODConsole::root->printRectEx(HM_WIDTH/2,HM_HEIGHT/2+1,HM_WIDTH/2-2,0,TCOD_BKGND_NONE,TCOD_CENTER,msg); TCODConsole::root->setDefaultBackground(TCODColor::lightBlue); if (h > 0 ) TCODConsole::root->rect(HM_WIDTH/4,HM_HEIGHT/2,HM_WIDTH/2,h+2,false,TCOD_BKGND_SET); TCODConsole::root->setDefaultBackground(TCODColor::black); } } void message(float delay,const char *fmt,...) { va_list ap; msgDelay=delay; va_start(ap,fmt); vsprintf(msg,fmt,ap); va_end(ap); } void backup() { // save the heightmap & RNG states for (int x=0; x < HM_WIDTH; x ++ ) { for (int y=0;y < HM_HEIGHT; y++ ) { hmold->setValue(x,y,hm->getValue(x,y)); } } if ( backupRnd ) delete backupRnd; backupRnd=rnd->save(); oldNormalized=isNormalized; oldmapmax=mapmax; oldmapmin=mapmin; } void restore() { // restore the previously saved heightmap & RNG states for (int x=0; x < HM_WIDTH; x ++ ) { for (int y=0;y < HM_HEIGHT; y++ ) { hm->setValue(x,y,hmold->getValue(x,y)); } } rnd->restore(backupRnd); isNormalized=oldNormalized; mapmax=oldmapmax; mapmin=oldmapmin; } void save() { // TODO message(2.0f,"Saved."); } void load() { // TODO } void addHill(int nbHill, float baseRadius, float radiusVar, float height) { for (int i=0; i< nbHill; i++ ) { float hillMinRadius=baseRadius*(1.0f-radiusVar); float hillMaxRadius=baseRadius*(1.0f+radiusVar); float radius = rnd->getFloat(hillMinRadius, hillMaxRadius); float theta = rnd->getFloat(0.0f, 6.283185f); // between 0 and 2Pi float dist = rnd->getFloat(0.0f, (float)MIN(HM_WIDTH,HM_HEIGHT)/2 - radius); int xh = (int) (HM_WIDTH/2 + cos(theta) * dist); int yh = (int) (HM_HEIGHT/2 + sin(theta) * dist); hm->addHill((float)xh,(float)yh,radius,height); } } void clearCbk(Widget *w,void *data) { hm->clear();Operation::clear(); history->clear(); params->clear(); params->setVisible(false); } void reseedCbk(Widget *w,void *data) { seed=rnd->getInt(0x7FFFFFFF,0xFFFFFFFF); Operation::reseed(); message(3.0f,"Switching to seed %X",seed); } void cancelCbk(Widget *w, void *data) { Operation::cancel(); } // operations buttons callbacks void normalizeCbk(Widget *w,void *data) { (new NormalizeOperation(0.0f,1.0f))->add(); } void addFbmCbk(Widget *w,void *data) { (new AddFbmOperation(1.0f,addFbmDelta,0.0f,6.0f,1.0f,0.5f))->add(); } void scaleFbmCbk(Widget *w, void *data) { (new ScaleFbmOperation(1.0f,addFbmDelta,0.0f,6.0f,1.0f,0.5f))->add(); } void addHillCbk(Widget *w,void *data) { (new AddHillOperation(25,10.0f,0.5f,(mapmax==mapmin ? 0.5f : (mapmax-mapmin)*0.1f)))->add(); } void rainErosionCbk(Widget *w,void *data) { (new RainErosionOperation(1000,0.05f,0.05f))->add(); } void smoothCbk(Widget *w,void *data) { (new SmoothOperation(mapmin,mapmax,2))->add(); } void voronoiCbk(Widget *w,void *data) { (new VoronoiOperation(100,2,voronoiCoef))->add(); } void noiseLerpCbk(Widget *w,void *data) { float v=(mapmax-mapmin)*0.5f; if (v == 0.0f ) v=1.0f; (new NoiseLerpOperation(0.0f,1.0f,addFbmDelta,0.0f,6.0f,v,v))->add(); } void raiseLowerCbk(Widget *w, void *data) { (new AddLevelOperation(0.0f))->add(); } // In/Out buttons callbacks void exportCCbk(Widget *w, void *data) { const char *code=Operation::buildCode(Operation::C); FILE *f=fopen("hm.c","wt"); fprintf(f,"%s",code); fclose(f); message(3.0f,"The code has been exported to ./hm.c"); } void exportPyCbk(Widget *w, void *data) { const char *code=Operation::buildCode(Operation::PY); FILE *f=fopen("hm.py","wt"); fprintf(f,"%s",code); fclose(f); message(3.0f,"The code has been exported to ./hm.py"); } void exportCppCbk(Widget *w, void *data) { const char *code=Operation::buildCode(Operation::CPP); FILE *f=fopen("hm.cpp","wt"); fprintf(f,"%s",code); fclose(f); message(3.0f,"The code has been exported to ./hm.cpp"); } void exportBmpCbk(Widget *w, void *data) { TCODImage img(HM_WIDTH,HM_HEIGHT); for (int x=0; x < HM_WIDTH; x++ ) { for (int y=0; y < HM_HEIGHT; y++ ) { float z = hm->getValue(x,y); uint8_t val=(uint8_t)(z*255); if ( slope ) { // render the slope map z = CLAMP(0.0f,1.0f,hm->getSlope(x,y)*10.0f); val = (uint8_t)(z*255); TCODColor c(val,val,val); img.putPixel(x,y,c); } else if ( greyscale ) { // render the greyscale heightmap TCODColor c(val,val,val); img.putPixel(x,y,c); } else if ( normal) { // render the normal map float n[3]; hm->getNormal((float)x,(float)y,n,mapmin); uint8_t r = (uint8_t)((n[0]*0.5f+0.5f)*255); uint8_t g = (uint8_t)((n[1]*0.5f+0.5f)*255); uint8_t b = (uint8_t)((n[2]*0.5f+0.5f)*255); TCODColor c(r,g,b); img.putPixel(x,y,c); } else { // render the colored heightmap img.putPixel(x,y,mapGradient[val]); } } } img.save("hm.bmp"); message(3.0f,"The bitmap has been exported to ./hm.bmp"); } // Display buttons callbacks void colorMapCbk(Widget *w, void *data) { slope=false; greyscale=false; normal=false; } void greyscaleCbk(Widget *w, void *data) { slope=false; greyscale=true; normal=false; } void slopeCbk(Widget *w, void *data) { slope=true; greyscale=false; normal=false; } void normalCbk(Widget *w, void *data) { slope=false; greyscale=false; normal=true; } void changeColorMapIdxCbk(Widget *w, float val, void *data) { intptr_t i=((intptr_t)data); keyIndex[i]=(int)(val); if ( i == 1 ) sandHeight = (float)(i)/255.0f; initColors(); } void changeColorMapRedCbk(Widget *w, float val, void *data) { intptr_t i=((intptr_t)data); keyColor[i].r=(int)(val); keyImages[i]->setBackgroundColor(keyColor[i]); initColors(); } void changeColorMapGreenCbk(Widget *w, float val, void *data) { intptr_t i=((intptr_t)data); keyColor[i].g=(int)(val); keyImages[i]->setBackgroundColor(keyColor[i]); initColors(); } void changeColorMapBlueCbk(Widget *w, float val, void *data) { intptr_t i=((intptr_t)data); keyColor[i].b=(int)(val); keyImages[i]->setBackgroundColor(keyColor[i]); initColors(); } void changeColorMapEndCbk(Widget *w, void *data) { colorMapGui->setVisible(false); } void changeColorMapCbk(Widget *w, void *data) { colorMapGui->move(w->x+w->w+2,w->y); colorMapGui->clear(); for (int i=0; i < nbColorKeys; i++ ) { char tmp[64]; sprintf(tmp,"Color %d",i); colorMapGui->addSeparator(tmp); HBox *hbox=new HBox(0,0,0); VBox *vbox=new VBox(0,0,0); colorMapGui->addWidget(hbox); Slider *idxSlider=new Slider(0,0,3,0.0f,255.0f,"index","Index of the key in the color map (0-255)"); idxSlider->setValue((float)keyIndex[i]); idxSlider->setFormat("%.0f"); idxSlider->setCallback(changeColorMapIdxCbk,(void *)i); vbox->addWidget(idxSlider); keyImages[i]=new Image(0,0,0,2); keyImages[i]->setBackgroundColor(keyColor[i]); vbox->addWidget(keyImages[i]); hbox->addWidget(vbox); vbox=new VBox(0,0,0); hbox->addWidget(vbox); Slider *redSlider=new Slider(0,0,3,0.0f,255.0f,"r","Red component of the color"); redSlider->setValue((float)keyColor[i].r); redSlider->setFormat("%.0f"); redSlider->setCallback(changeColorMapRedCbk,(void *)i); vbox->addWidget(redSlider); Slider *greenSlider=new Slider(0,0,3,0.0f,255.0f,"g","Green component of the color"); greenSlider->setValue((float)keyColor[i].g); greenSlider->setFormat("%.0f"); greenSlider->setCallback(changeColorMapGreenCbk,(void *)i); vbox->addWidget(greenSlider); Slider *blueSlider = new Slider(0,0,3,0.0f,255.0f,"b","Blue component of the color"); blueSlider->setValue((float)keyColor[i].b); blueSlider->setFormat("%.0f"); blueSlider->setCallback(changeColorMapBlueCbk,(void *)i); vbox->addWidget(blueSlider); } colorMapGui->addWidget(new Button("Ok",NULL,changeColorMapEndCbk,NULL)); colorMapGui->setVisible(true); } // build gui void addOperationButton(ToolBar *tools, Operation::OpType type, void (*cbk)(Widget *w,void *data)){ tools->addWidget(new Button(Operation::names[type],Operation::tips[type],cbk,NULL)); } void buildGui() { // status bar new StatusBar(0,0,HM_WIDTH,1); VBox *vbox=new VBox(0,2,1); // stats ToolBar *stats = new ToolBar(0,0,21,"Stats","Statistics about the current map"); stats->addWidget(new Label(0,0,landMassTxt,"Ratio of land surface / total surface")); stats->addWidget(new Label(0,0,minZTxt,"Minimum z value in the map")); stats->addWidget(new Label(0,0,maxZTxt,"Maximum z value in the map")); stats->addWidget(new Label(0,0,seedTxt,"Current random seed used to build the map")); vbox->addWidget(stats); // tools ToolBar *tools=new ToolBar(0,0,15,"Tools","Tools to modify the heightmap"); tools->addWidget(new Button("cancel","Delete the selected operation",cancelCbk,NULL)); tools->addWidget(new Button("clear","Remove all operations and reset all heightmap values to 0.0",clearCbk,NULL)); tools->addWidget(new Button("reseed","Replay all operations with a new random seed",reseedCbk,NULL)); // operations tools->addSeparator("Operations","Apply a new operation to the map"); addOperationButton(tools,Operation::NORM,normalizeCbk); addOperationButton(tools,Operation::ADDFBM,addFbmCbk); addOperationButton(tools,Operation::SCALEFBM,scaleFbmCbk); addOperationButton(tools,Operation::ADDHILL,addHillCbk); addOperationButton(tools,Operation::RAIN,rainErosionCbk); addOperationButton(tools,Operation::SMOOTH,smoothCbk); addOperationButton(tools,Operation::VORONOI,voronoiCbk); addOperationButton(tools,Operation::NOISELERP,noiseLerpCbk); addOperationButton(tools,Operation::ADDLEVEL,raiseLowerCbk); // display tools->addSeparator("Display","Change the type of display"); RadioButton::setDefaultGroup(1); RadioButton *colormap=new RadioButton("colormap","Enable colormap mode",colorMapCbk,NULL); tools->addWidget(colormap); colormap->select(); tools->addWidget(new RadioButton("slope","Enable slope mode",slopeCbk,NULL)); tools->addWidget(new RadioButton("greyscale","Enable greyscale mode",greyscaleCbk,NULL)); tools->addWidget(new RadioButton("normal","Enable normal map mode",normalCbk,NULL)); tools->addWidget(new Button("change colormap","Modify the colormap used by hmtool", changeColorMapCbk,NULL)); // change colormap gui colorMapGui=new ToolBar(0,0,"Colormap","Select the color and position of the keys in the color map"); colorMapGui->setVisible(false); // in/out tools->addSeparator("In/Out","Import/Export stuff"); tools->addWidget(new Button("export C","Generate the C code for this heightmap in ./hm.c",exportCCbk,NULL)); tools->addWidget(new Button("export CPP","Generate the CPP code for this heightmap in ./hm.cpp",exportCppCbk,NULL)); tools->addWidget(new Button("export PY","Generate the Python code for this heightmap in ./hm.py",exportPyCbk,NULL)); tools->addWidget(new Button("export bmp","Save this heightmap as a bitmap in ./hm.bmp",exportBmpCbk,NULL)); vbox->addWidget(tools); // params box params = new ToolBar(0,0,"Params","Parameters of the current tool"); vbox->addWidget(params); params->setVisible(false); // history history = new ToolBar(0,tools->y+1+tools->h,15,"History","History of operations"); vbox->addWidget(history); } int main(int argc, char *argv[]) { TCODConsole::initRoot(HM_WIDTH,HM_HEIGHT,"height map tool",false); guicon = new TCODConsole(HM_WIDTH,HM_HEIGHT); guicon->setKeyColor(TCODColor(255,0,255)); Widget::setConsole(guicon); TCODSystem::setFps(25); initColors(); buildGui(); hm = new TCODHeightMap(HM_WIDTH,HM_HEIGHT); hmold = new TCODHeightMap(HM_WIDTH,HM_HEIGHT); rnd=new TCODRandom(seed); noise=new TCODNoise(2,rnd); uint8_t fade=50; bool creditsEnd=false; while ( ! TCODConsole::isWindowClosed() ) { render(); guicon->setDefaultBackground(TCODColor(255,0,255)); guicon->clear(); Widget::renderWidgets(); if (! creditsEnd ) { creditsEnd=TCODConsole::renderCredits(HM_WIDTH-20,HM_HEIGHT-7,true); } if ( Widget::focus ) { if ( fade < 200 ) fade += 20; } else { if ( fade > 80 ) fade -= 20; } TCODConsole::blit(guicon,0,0,HM_WIDTH,HM_HEIGHT,TCODConsole::root,0,0,fade/255.0f,fade/255.0f); TCODConsole::flush(); TCOD_key_t key; TCOD_mouse_t mouse; TCODSystem::checkForEvent(TCOD_EVENT_KEY_PRESS|TCOD_EVENT_MOUSE,&key,&mouse); Widget::updateWidgets(key,mouse); switch(key.c) { case '+' : (new AddLevelOperation((mapmax-mapmin)/50))->run(); break; case '-' : (new AddLevelOperation(-(mapmax-mapmin)/50))->run(); break; default:break; } switch(key.vk) { case TCODK_PRINTSCREEN : TCODSystem::saveScreenshot(NULL); break; default:break; } } return 0; } libtcod-1.6.4+dfsg/samples/hmtool/operation.cpp000066400000000000000000000771271321276576200215640ustar00rootroot00000000000000#include #include #include "libtcod.hpp" #include "gui/gui.hpp" #include "operation.hpp" // must match Operation::OpType enum const char *Operation::names[]= { "norm", "+fbm", "*fbm", "hill", "\x18\x19 z", "smooth", "rain", "lerp fbm", "voronoi", }; const char *Operation::tips[]= { "Normalize heightmap so that values are between 0.0 and 1.0", "Add fbm noise to current heightmap", "Scale the heightmap by a fbm noise", "Add random hills on the heightmap", "[+/-] Raise or lower the whole heightmap", "Smooth the heightmap", "Simulate rain erosion on the heightmap", "Lerp between the heightmap and a fbm noise", "Add a voronoi diagram to the heightmap", }; static const char *header1[] = { // C header "#include \n" "#include \"libtcod.h\"\n" "// size of the heightmap\n" "#define HM_WIDTH 100\n" "#define HM_HEIGHT 80\n", // CPP header "#include \"libtcod.hpp\"\n" "// size of the heightmap\n" "#define HM_WIDTH 100\n" "#define HM_HEIGHT 80\n", // PY header "#!/usr/bin/python\n" "import math\n" "import libtcodpy as libtcod\n" "# size of the heightmap\n" "HM_WIDTH=100\n" "HM_HEIGHT=80\n", }; static const char *header2[] = { // C header 2 "// function building the heightmap\n" "void buildMap(TCOD_heightmap_t *hm) {\n", // CPP header 2 "// function building the heightmap\n" "void buildMap(TCODHeightMap *hm) {\n", // PY header 2 "# function building the heightmap\n" "def buildMap(hm) :\n", }; static const char *footer1[] = { // C footer "}\n" "// test code to print the heightmap\n" "// to compile this file on Linux :\n" "// gcc hm.c -o hm -I include/ -L . -ltcod\n" "// to compile this file on Windows/mingw32 :\n" "// gcc hm.c -o hm.exe -I include/ -L lib -ltcod-mingw\n" "int main(int argc, char *argv[]) {\n" "\tint x,y;\n" "\tTCOD_heightmap_t *hm=TCOD_heightmap_new(HM_WIDTH,HM_HEIGHT);\n", // CPP footer "}\n" "// test code to print the heightmap\n" "// to compile this file on Linux :\n" "// g++ hm.cpp -o hm -I include/ -L . -ltcod -ltcod++\n" "// to compile this file on Windows/mingw32 :\n" "// g++ hm.cpp -o hm.exe -I include/ -L lib -ltcod-mingw\n" "int main(int argc, char *argv[]) {\n" "\tTCODHeightMap hm(HM_WIDTH,HM_HEIGHT);\n" "\tbuildMap(&hm);\n" "\tTCODConsole::initRoot(HM_WIDTH,HM_HEIGHT,\"height map test\",false);\n" "\tfor (int x=0; x < HM_WIDTH; x ++ ) {\n" "\t\tfor (int y=0;y < HM_HEIGHT; y++ ) {\n" "\t\t\tfloat z = hm.getValue(x,y);\n" "\t\t\tuint8_t val=(uint8_t)(z*255);\n" "\t\t\tTCODColor c(val,val,val);\n" "\t\t\tTCODConsole::root->setCharBackground(x,y,c);\n" "\t\t}\n" "\t}\n" "\tTCODConsole::root->flush();\n" "\tTCODConsole::waitForKeypress(true);\n" "\treturn 0;\n" "}\n", // PY footer "# test code to print the heightmap\n" "hm=libtcod.heightmap_new(HM_WIDTH,HM_HEIGHT)\n" "buildMap(hm)\n" "libtcod.console_init_root(HM_WIDTH,HM_HEIGHT,\"height map test\",False)\n" "for x in range(HM_WIDTH) :\n" " for y in range(HM_HEIGHT) :\n" " z = libtcod.heightmap_get_value(hm,x,y)\n" " val=int(z*255) & 0xFF\n" " c=libtcod.Color(val,val,val)\n" " libtcod.console_set_char_background(None,x,y,c,libtcod.BKGND_SET)\n" "libtcod.console_flush()\n" "libtcod.console_wait_for_keypress(True)\n", }; static const char *footer2[] = { // C footer "\tbuildMap(hm);\n" "\tTCOD_console_init_root(HM_WIDTH,HM_HEIGHT,\"height map test\",false);\n" "\tfor (x=0; x < HM_WIDTH; x ++ ) {\n" "\t\tfor (y=0;y < HM_HEIGHT; y++ ) {\n" "\t\t\tfloat z = TCOD_heightmap_get_value(hm,x,y);\n" "\t\t\tuint8_t val=(uint8_t)(z*255);\n" "\t\t\tTCOD_color_t c={val,val,val};\n" "\t\t\tTCOD_console_set_char_background(NULL,x,y,c,TCOD_BKGND_SET);\n" "\t\t}\n" "\t}\n" "\tTCOD_console_flush();\n" "\tTCOD_console_wait_for_keypress(true);\n" "\treturn 0;\n" "}\n", // CPP footer "", // PY footer "", }; TCODList Operation::list; char *Operation::codebuf=NULL; int Operation::bufSize=0,Operation::freeSize=0; TCODList Operation::initCode[Operation::NB_CODE]; bool Operation::needsRandom=false; bool Operation::needsNoise=false; Operation *Operation::currentOp=NULL; void Operation::addCode(const char *code) { int len=strlen(code); if ( len+1 > freeSize ) { int newSize=bufSize + MAX(4096,len+1); char *newbuf = new char[ newSize ]; newbuf[0]=0; if ( codebuf ) { strcpy(newbuf,codebuf); delete [] codebuf; } codebuf = newbuf; freeSize += newSize - bufSize; bufSize=newSize; } strcat(codebuf,code); freeSize -= len; } const char * Operation::format(const char *fmt, ...) { static char tmp[4096]; va_list ap; va_start(ap,fmt); vsprintf(tmp,fmt,ap); va_end(ap); return tmp; } const char *Operation::buildCode(CodeType type) { if ( codebuf ) { codebuf[0]=0; freeSize=bufSize; } addCode(header1[type]); if (needsRandom || needsNoise ) { switch(type) { case(C) : addCode(format("TCOD_random_t rnd=NULL;\n",seed)); break; case(CPP) : addCode(format("TCODRandom *rnd=new TCODRandom(%uU);\n",seed)); break; case(PY) : addCode(format("rnd=libtcod.random_new_from_seed(%u)\n",seed)); break; default:break; } } if (needsNoise ) { switch(type) { case(C) : addCode("TCOD_noise_t noise=NULL;\n"); break; case(CPP) : addCode("TCODNoise *noise=new TCODNoise(2,rnd);\n"); break; case(PY) : addCode("noise=libtcod.noise_new(2,libtcod.NOISE_DEFAULT_HURST,libtcod.NOISE_DEFAULT_LACUNARITY,rnd)\n"); break; default:break; } } for (const char **s=initCode[type].begin(); s!=initCode[type].end(); s++) { addCode(*s); } addCode(header2[type]); for (Operation **op=list.begin(); op!=list.end(); op++) { const char *code=(*op)->getCode(type); addCode(code); } addCode(footer1[type]); if ((needsRandom || needsNoise) && type == C ) { addCode(format("\trnd=TCOD_random_new_from_seed(%uU);\n",seed)); if (needsNoise) { addCode("\tnoise=TCOD_noise_new(2,TCOD_NOISE_DEFAULT_HURST,TCOD_NOISE_DEFAULT_LACUNARITY,rnd);\n"); } } addCode(footer2[type]); return codebuf; } void Operation::run() { runInternal(); } void historyCbk(Widget *w,void *data) { Operation *op=(Operation *)data; op->createParamUi(); op->button->select(); Operation::currentOp=op; } void Operation::add() { backup(); runInternal(); if ( addInternal() ) { list.push(this); createParamUi(); button=new RadioButton(names[type],tips[type],historyCbk,this); button->setGroup(0); history->addWidget(button); button->select(); currentOp=this; } else delete this; } void Operation::clear() { list.clearAndDelete(); } void Operation::createParamUi() { params->clear(); params->setVisible(false); } void Operation::cancel() { if ( currentOp ) { list.remove(currentOp); history->removeWidget(currentOp->button); currentOp->button->unSelect(); delete currentOp; currentOp=list.peek(); if ( currentOp ) { currentOp->button->select(); currentOp->createParamUi(); } else { params->clear(); params->setVisible(false); } reseed(); // replay the whole stack } } void Operation::addInitCode(CodeType type,const char *code) { if (! initCode[type].contains(code) ) initCode[type].push(code); } void Operation::reseed() { delete rnd; rnd = new TCODRandom(seed); delete noise; noise=new TCODNoise(2,rnd); addFbmDelta=scaleFbmDelta=0.0f; hm->clear(); for (Operation **op=list.begin(); op!=list.end();op++) { (*op)->runInternal(); } } // ********** actual operations below ********** // Normalize const char *NormalizeOperation::getCode(CodeType type) { switch(type) { case C : return format("\tTCOD_heightmap_normalize(hm,%g,%g);\n",min,max); break; case CPP : return format("\thm->normalize(%g,%g);\n",min,max); break; case PY : return format(" libtcod.heightmap_normalize(hm,%g,%g)\n",min,max); break; default:break; } return NULL; } void NormalizeOperation::runInternal() { hm->normalize(min,max); } bool NormalizeOperation::addInternal() { Operation *prev=list.peek(); if ( prev && prev->type == NORM ) { return false; } return true; } void normalizeMinValueCbk(Widget *wid, char * val, void * data) { #ifdef TCOD_VISUAL_STUDIO float f=(float)atof(val); { #else char *endptr; float f=strtof(val,&endptr); if ( f != 0.0f || endptr != val ) { #endif NormalizeOperation *op=(NormalizeOperation *)data; if ( f < op->max ) { op->min=f; if ( Operation::list.peek() == op ) { op->run(); } else { Operation::reseed(); } } } } void normalizeMaxValueCbk(Widget *wid, char * val, void *data) { #ifdef TCOD_VISUAL_STUDIO float f=(float)atof(val); { #else char *endptr; float f=strtof(val,&endptr); if ( f != 0.0f || endptr != val ) { #endif NormalizeOperation *op=(NormalizeOperation *)data; if ( f > op->min ) { op->max=f; if ( Operation::list.peek() == op ) { op->run(); } else { Operation::reseed(); } } } } void NormalizeOperation::createParamUi() { params->clear(); params->setVisible(true); params->setName(names[NORM]); char tmp[64]; sprintf(tmp,"%g",min); TextBox *tbMin=new TextBox(0,0,8,10,"min",tmp,"Heightmap minimum value after the normalization"); tbMin->setCallback(normalizeMinValueCbk,this); params->addWidget(tbMin); sprintf(tmp,"%g",max); TextBox *tbMax=new TextBox(0,0,8,10,"max",tmp,"Heightmap maximum value after the normalization"); tbMax->setCallback(normalizeMaxValueCbk,this); params->addWidget(tbMax); } // AddFbm const char *AddFbmOperation::getCode(CodeType type) { switch(type) { case C : return format( "\tTCOD_heightmap_add_fbm(hm,noise,%g,%g,%g,%g,%g,%g,%g);\n", zoom,zoom,offsetx,offsety,octaves,offset,scale); break; case CPP : return format( "\thm->addFbm(noise,%g,%g,%g,%g,%g,%g,%g);\n", zoom,zoom,offsetx,offsety,octaves,offset,scale); break; case PY : return format( " libtcod.heightmap_add_fbm(hm,noise,%g,%g,%g,%g,%g,%g,%g)\n", zoom,zoom,offsetx,offsety,octaves,offset,scale); break; default:break; } return NULL; } void AddFbmOperation::runInternal() { hm->addFbm(noise,zoom,zoom,offsetx,offsety,octaves,offset,scale); } bool AddFbmOperation::addInternal() { needsNoise=true; addFbmDelta += HM_WIDTH; return true; } void addFbmZoomValueCbk(Widget *wid, float val, void *data) { AddFbmOperation *op=(AddFbmOperation *)data; op->zoom=val; if ( Operation::list.peek() == op ) { restore(); op->run(); } else { Operation::reseed(); } } void addFbmXOffsetValueCbk(Widget *wid, float val, void *data) { AddFbmOperation *op=(AddFbmOperation *)data; op->offsetx=val; if ( Operation::list.peek() == op ) { restore(); op->run(); } else { Operation::reseed(); } } void addFbmYOffsetValueCbk(Widget *wid, float val, void *data) { AddFbmOperation *op=(AddFbmOperation *)data; op->offsety=val; if ( Operation::list.peek() == op ) { restore(); op->run(); } else { Operation::reseed(); } } void addFbmOctavesValueCbk(Widget *wid, float val, void *data) { AddFbmOperation *op=(AddFbmOperation *)data; op->octaves=val; if ( Operation::list.peek() == op ) { restore(); op->run(); } else { Operation::reseed(); } } void addFbmOffsetValueCbk(Widget *wid, float val, void *data) { AddFbmOperation *op=(AddFbmOperation *)data; op->offset=val; if ( Operation::list.peek() == op ) { restore(); op->run(); } else { Operation::reseed(); } } void addFbmScaleValueCbk(Widget *wid, float val, void *data) { AddFbmOperation *op=(AddFbmOperation *)data; op->scale=val; if ( Operation::list.peek() == op ) { restore(); op->run(); } else { Operation::reseed(); } } void AddFbmOperation::createParamUi() { params->clear(); params->setVisible(true); params->setName(names[ADDFBM]); Slider *slider=new Slider(0,0,8,0.1f,20.0f,"zoom ","Noise zoom"); slider->setCallback(addFbmZoomValueCbk,this); params->addWidget(slider); slider->setValue(zoom); slider=new Slider(0,0,8,-100.0f,100.0f,"xOffset ","Horizontal offset in the noise plan"); slider->setCallback(addFbmXOffsetValueCbk,this); params->addWidget(slider); slider->setValue(offsetx); slider=new Slider(0,0,8,-100.0f,100.0f,"yOffset ","Vertical offset in the noise plan"); slider->setCallback(addFbmYOffsetValueCbk,this); params->addWidget(slider); slider->setValue(offsety); slider=new Slider(0,0,8,1.0f,10.0f,"octaves ","Number of octaves for the fractal sum"); slider->setCallback(addFbmOctavesValueCbk,this); params->addWidget(slider); slider->setValue(octaves); slider=new Slider(0,0,8,-1.0f,1.0f,"noiseOffset","Offset added to the noise value"); slider->setCallback(addFbmOffsetValueCbk,this); params->addWidget(slider); slider->setValue(offset); slider=new Slider(0,0,8,0.01f,10.0f,"scale ","The noise value is multiplied by this value"); slider->setCallback(addFbmScaleValueCbk,this); params->addWidget(slider); slider->setValue(scale); } // ScaleFbm const char *ScaleFbmOperation::getCode(CodeType type) { switch(type) { case C : return format( "\tTCOD_heightmap_scale_fbm(hm,noise,%g,%g,%g,%g,%g,%g,%g);\n" "\tscaleFbmDelta += HM_WIDTH;\n", zoom,zoom,offsetx,offsety,octaves,offset,scale); break; case CPP : return format( "\thm->scaleFbm(noise,%g,%g,%g,%g,%g,%g,%g);\n" "\tscaleFbmDelta += HM_WIDTH;\n", zoom,zoom,offsetx,offsety,octaves,offset,scale); break; case PY : return format( " libtcod.heightmap_scale_fbm(hm,noise,%g,%g,%g,%g,%g,%g,%g)\n" " scaleFbmDelta += HM_WIDTH\n", zoom,zoom,offsetx,offsety,octaves,offset,scale); break; default:break; } return NULL; } void ScaleFbmOperation::runInternal() { hm->scaleFbm(noise,zoom,zoom,offsetx,offsety,octaves,offset,scale); } bool ScaleFbmOperation::addInternal() { needsNoise=true; scaleFbmDelta += HM_WIDTH; return true; } // AddHill const char *AddHillOperation::getCode(CodeType type) { switch(type) { case C : return format("\taddHill(hm,%d,%g,%g,%g);\n",nbHill, radius, radiusVar, height); break; case CPP : return format("\taddHill(hm,%d,%g,%g,%g);\n",nbHill, radius, radiusVar, height); break; case PY : return format(" addHill(hm,%d,%g,%g,%g)\n",nbHill, radius, radiusVar, height); break; default:break; } return NULL; } void AddHillOperation::runInternal() { addHill( nbHill, radius, radiusVar, height); } bool AddHillOperation::addInternal() { addInitCode(C, "#include \n" "void addHill(TCOD_heightmap_t *hm,int nbHill, float baseRadius, float radiusVar, float height) {\n" "\tint i;\n" "\tfor (i=0; i< nbHill; i++ ) {\n" "\t\tfloat hillMinRadius=baseRadius*(1.0f-radiusVar);\n" "\t\tfloat hillMaxRadius=baseRadius*(1.0f+radiusVar);\n" "\t\tfloat radius = TCOD_random_get_float(rnd,hillMinRadius, hillMaxRadius);\n" "\t\tfloat theta = TCOD_random_get_float(rnd,0.0f, 6.283185f); // between 0 and 2Pi\n" "\t\tfloat dist = TCOD_random_get_float(rnd,0.0f, (float)MIN(HM_WIDTH,HM_HEIGHT)/2 - radius);\n" "\t\tint xh = (int) (HM_WIDTH/2 + cos(theta) * dist);\n" "\t\tint yh = (int) (HM_HEIGHT/2 + sin(theta) * dist);\n" "\t\tTCOD_heightmap_add_hill(hm,(float)xh,(float)yh,radius,height);\n" "\t}\n" "}\n"); addInitCode(CPP, "#include \n" "void addHill(TCODHeightMap *hm,int nbHill, float baseRadius, float radiusVar, float height) {\n" "\tfor (int i=0; i< nbHill; i++ ) {\n" "\t\tfloat hillMinRadius=baseRadius*(1.0f-radiusVar);\n" "\t\tfloat hillMaxRadius=baseRadius*(1.0f+radiusVar);\n" "\t\tfloat radius = rnd->getFloat(hillMinRadius, hillMaxRadius);\n" "\t\tfloat theta = rnd->getFloat(0.0f, 6.283185f); // between 0 and 2Pi\n" "\t\tfloat dist = rnd->getFloat(0.0f, (float)MIN(HM_WIDTH,HM_HEIGHT)/2 - radius);\n" "\t\tint xh = (int) (HM_WIDTH/2 + cos(theta) * dist);\n" "\t\tint yh = (int) (HM_HEIGHT/2 + sin(theta) * dist);\n" "\t\thm->addHill((float)xh,(float)yh,radius,height);\n" "\t}\n" "}\n"); addInitCode(PY, "def addHill(hm,nbHill,baseRadius,radiusVar,height) :\n" " for i in range(nbHill) :\n" " hillMinRadius=baseRadius*(1.0-radiusVar)\n" " hillMaxRadius=baseRadius*(1.0+radiusVar)\n" " radius = libtcod.random_get_float(rnd,hillMinRadius, hillMaxRadius)\n" " theta = libtcod.random_get_float(rnd,0.0, 6.283185) # between 0 and 2Pi\n" " dist = libtcod.random_get_float(rnd,0.0, float(min(HM_WIDTH,HM_HEIGHT))/2 - radius)\n" " xh = int(HM_WIDTH/2 + math.cos(theta) * dist)\n" " yh = int(HM_HEIGHT/2 + math.sin(theta) * dist)\n" " libtcod.heightmap_add_hill(hm,float(xh),float(yh),radius,height)\n" ); return true; } void addHillNbHillValueCbk(Widget *wid, float val, void *data) { AddHillOperation *op=(AddHillOperation *)data; op->nbHill=(int)val; if ( Operation::list.peek() == op ) { restore(); op->run(); } else { Operation::reseed(); } } void addHillRadiusValueCbk(Widget *wid, float val, void *data) { AddHillOperation *op=(AddHillOperation *)data; op->radius=val; if ( Operation::list.peek() == op ) { restore(); op->run(); } else { Operation::reseed(); } } void addHillRadiusVarValueCbk(Widget *wid, float val, void *data) { AddHillOperation *op=(AddHillOperation *)data; op->radiusVar=val; if ( Operation::list.peek() == op ) { restore(); op->run(); } else { Operation::reseed(); } } void addHillHeightValueCbk(Widget *wid, float val, void *data) { AddHillOperation *op=(AddHillOperation *)data; op->height=val; if ( Operation::list.peek() == op ) { restore(); op->run(); } else { Operation::reseed(); } } void AddHillOperation::createParamUi() { params->clear(); params->setVisible(true); params->setName(names[ADDHILL]); Slider *slider=new Slider(0,0,8,1.0f,50.0f,"nbHill ","Number of hills"); slider->setCallback(addHillNbHillValueCbk,this); slider->setFormat("%.0f"); slider->setSensitivity(2.0f); params->addWidget(slider); slider->setValue((float)nbHill); slider=new Slider(0,0,8,1.0f,30.0f,"radius ","Average radius of the hills"); slider->setCallback(addHillRadiusValueCbk,this); slider->setFormat("%.1f"); params->addWidget(slider); slider->setValue(radius); slider=new Slider(0,0,8,0.0f,1.0f,"radiusVar","Variation of the radius of the hills"); slider->setCallback(addHillRadiusVarValueCbk,this); params->addWidget(slider); slider->setValue(radiusVar); slider=new Slider(0,0,8,0.0f,(mapmax==mapmin ? 1.0f : (mapmax-mapmin)*0.5f),"height ","Height of the hills"); slider->setCallback(addHillHeightValueCbk,this); params->addWidget(slider); slider->setValue(height); } // AddLevel const char *AddLevelOperation::getCode(CodeType type) { switch(type) { case C : return format("\tTCOD_heightmap_add(hm,%g);\n\tTCOD_heightmap_clamp(hm,0.0f,1.0f);\n",level); break; case CPP : return format("\thm->add(%g);\n\thm->clamp(0.0f,1.0f);\n",level); break; case PY : return format(" libtcod.heightmap_add(hm,%g)\n libtcod.heightmap_clamp(hm,0.0,1.0)\n",level); break; default:break; } return NULL; } void AddLevelOperation::runInternal() { float min,max; hm->getMinMax(&min,&max); hm->add(level);if ( min != max ) hm->clamp(min,max); } bool AddLevelOperation::addInternal() { Operation *prev=list.peek(); bool ret=true; if ( prev && prev->type == ADDLEVEL ) { // cumulated consecutive addLevel operation into a single call AddLevelOperation *addOp=(AddLevelOperation *)prev; if (addOp->level * level > 0 ) { addOp->level += level; ret=false; } } return ret; } void raiseLowerValueCbk(Widget *wid, float val, void *data) { AddLevelOperation *op=(AddLevelOperation *)data; op->level = val; if (op == Operation::list.peek()) { restore(); op->run(); } else { Operation::reseed(); } } void AddLevelOperation::createParamUi() { params->clear(); params->setName(names[ADDLEVEL]); params->setVisible(true); Slider *slider=new Slider(0,0,8,-1.0f,1.0f,"zOffset","z value to add to the whole map"); slider->setCallback(raiseLowerValueCbk,this); params->addWidget(slider); float minLevel,maxLevel; hm->getMinMax(&minLevel,&maxLevel); if ( maxLevel == minLevel ) slider->setMinMax(-1.0f,1.0f); else slider->setMinMax(-(maxLevel-minLevel),(maxLevel-minLevel)); slider->setValue(level); } // Smooth const char *SmoothOperation::getCode(CodeType type) { switch(type) { case C : return format( "\tsmoothKernelWeight[4] = %g;\n" "\t{\n" "\t\tint i;\n" "\t\tfor (i=%d; i>= 0; i--) {\n" "\t\t\tTCOD_heightmap_kernel_transform(hm,smoothKernelSize,smoothKernelDx,smoothKernelDy,smoothKernelWeight,%g,%g);\n" "\t\t}\n" "\t}\n", 20 - radius*19,count,minLevel,maxLevel); break; case CPP : return format( "\tsmoothKernelWeight[4] = %g;\n" "\tfor (int i=%d; i>= 0; i--) {\n" "\t\thm->kernelTransform(smoothKernelSize,smoothKernelDx,smoothKernelDy,smoothKernelWeight,%g,%g);\n" "\t}\n", 20 - radius*19,count,minLevel,maxLevel); break; case PY : return format( " smoothKernelWeight[4] = %g\n" " for i in range(%d,-1,-1) :\n" " libtcod.heightmap_kernel_transform(hm,smoothKernelSize,smoothKernelDx,smoothKernelDy,smoothKernelWeight,%g,%g)\n", 20 - radius*19,count,minLevel,maxLevel); break; default:break; } return NULL; } void SmoothOperation::runInternal() { smoothKernelWeight[4] = 20 - radius*19; for (int i=count; i>= 0; i--) { hm->kernelTransform(smoothKernelSize,smoothKernelDx,smoothKernelDy,smoothKernelWeight,minLevel,maxLevel); } } bool SmoothOperation::addInternal() { addInitCode(C, "// 3x3 kernel for smoothing operations\n" "int smoothKernelSize=9;\n" "int smoothKernelDx[9]={-1,0,1,-1,0,1,-1,0,1};\n" "int smoothKernelDy[9]={-1,-1,-1,0,0,0,1,1,1};\n" "float smoothKernelWeight[9]={1,2,1,2,20,2,1,2,1};\n" ); addInitCode(CPP, "// 3x3 kernel for smoothing operations\n" "int smoothKernelSize=9;\n" "int smoothKernelDx[9]={-1,0,1,-1,0,1,-1,0,1};\n" "int smoothKernelDy[9]={-1,-1,-1,0,0,0,1,1,1};\n" "float smoothKernelWeight[9]={1,2,1,2,20,2,1,2,1};\n" ); addInitCode(PY, "# 3x3 kernel for smoothing operations\n" "smoothKernelSize=9\n" "smoothKernelDx=[-1,0,1,-1,0,1,-1,0,1]\n" "smoothKernelDy=[-1,-1,-1,0,0,0,1,1,1]\n" "smoothKernelWeight=[1.0,2.0,1.0,2.0,20.0,2.0,1.0,2.0,1.0]\n" ); return true; } void smoothMinValueCbk(Widget *wid, float val, void *data) { SmoothOperation *op=(SmoothOperation *)data; op->minLevel = val; if (op == Operation::list.peek()) { restore(); op->run(); } else { Operation::reseed(); } } void smoothMaxValueCbk(Widget *wid, float val, void *data) { SmoothOperation *op=(SmoothOperation *)data; op->maxLevel = val; if (op == Operation::list.peek()) { restore(); op->run(); } else { Operation::reseed(); } } void smoothRadiusValueCbk(Widget *wid, float val, void *data) { SmoothOperation *op=(SmoothOperation *)data; op->radius = val; if (op == Operation::list.peek()) { restore(); op->run(); } else { Operation::reseed(); } } void smoothCountValueCbk(Widget *wid, float val, void *data) { SmoothOperation *op=(SmoothOperation *)data; op->count = (int)val; if (op == Operation::list.peek()) { restore(); op->run(); } else { Operation::reseed(); } } void SmoothOperation::createParamUi() { params->clear(); params->setName(names[SMOOTH]); params->setVisible(true); Slider *slider=new Slider(0,0,8,MIN(0.0f,minLevel),MAX(1.0f,maxLevel),"minLevel","Land level above which the smooth operation is applied"); slider->setCallback(smoothMinValueCbk,this); params->addWidget(slider); slider->setValue(minLevel); slider=new Slider(0,0,8,MIN(0.0f,minLevel),MAX(1.0f,maxLevel),"maxLevel","Land level below which the smooth operation is applied"); slider->setCallback(smoothMaxValueCbk,this); params->addWidget(slider); slider->setValue(maxLevel); slider=new Slider(0,0,8,1.0f,20.0f,"amount","Number of times the smoothing operation is applied"); slider->setCallback(smoothCountValueCbk,this); slider->setFormat("%.0f"); slider->setSensitivity(4.0f); params->addWidget(slider); slider->setValue((float)count); slider=new Slider(0,0,8,0.0f,1.0f,"sharpness","Radius of the blurring effect"); slider->setCallback(smoothRadiusValueCbk,this); params->addWidget(slider); slider->setValue(0.0f); } // Rain const char *RainErosionOperation::getCode(CodeType type) { switch(type) { case C : return format("\tTCOD_heightmap_rain_erosion(hm,%d,%g,%g,rnd);\n",nbDrops,erosionCoef,sedimentationCoef); break; case CPP : return format("\thm->rainErosion(%d,%g,%g,rnd);\n",nbDrops,erosionCoef,sedimentationCoef); break; case PY : return format(" libtcod.heightmap_rain_erosion(hm,%d,%g,%g,rnd)\n",nbDrops,erosionCoef,sedimentationCoef); break; default:break; } return NULL; } void RainErosionOperation::runInternal() { if ( !isNormalized ) { hm->normalize(); } hm->rainErosion(nbDrops,erosionCoef,sedimentationCoef,rnd); } bool RainErosionOperation::addInternal() { needsRandom=true; return true; } void rainErosionNbDropsValueCbk(Widget *wid, float val, void *data) { RainErosionOperation *op=(RainErosionOperation *)data; op->nbDrops = (int)val; if (op == Operation::list.peek()) { restore(); op->run(); } else { Operation::reseed(); } } void rainErosionErosionCoefValueCbk(Widget *wid, float val, void *data) { RainErosionOperation *op=(RainErosionOperation *)data; op->erosionCoef = val; if (op == Operation::list.peek()) { restore(); op->run(); } else { Operation::reseed(); } } void rainErosionSedimentationCoefValueCbk(Widget *wid, float val, void *data) { RainErosionOperation *op=(RainErosionOperation *)data; op->sedimentationCoef = val; if (op == Operation::list.peek()) { restore(); op->run(); } else { Operation::reseed(); } } void RainErosionOperation::createParamUi() { params->clear(); params->setName(names[RAIN]); params->setVisible(true); Slider *slider=new Slider(0,0,8,1000.0f,20000.0f,"nbDrops ","Number of rain drops simulated"); slider->setCallback(rainErosionNbDropsValueCbk,this); params->addWidget(slider); slider->setFormat("%.0f"); slider->setValue((float)nbDrops); slider=new Slider(0,0,8,0.01f,1.0f,"erosion ","Erosion effect amount"); slider->setCallback(rainErosionErosionCoefValueCbk,this); params->addWidget(slider); slider->setValue(erosionCoef); slider=new Slider(0,0,8,0.01f,1.0f,"sedimentation","Sedimentation effect amount"); slider->setCallback(rainErosionSedimentationCoefValueCbk,this); params->addWidget(slider); slider->setValue(sedimentationCoef); } // NoiseLerp const char *NoiseLerpOperation::getCode(CodeType type) { switch(type) { case C : return format( "\t{\n" "\t\tTCOD_heightmap_t *tmp=TCOD_heightmap_new(HM_WIDTH,HM_HEIGHT);\n" "\t\tTCOD_heightmap_add_fbm(tmp,noise,%g,%g,%g,%g,%g,%g,%g);\n" "\t\tTCOD_heightmap_lerp(hm,tmp,hm,%g);\n" "\t\tTCOD_heightmap_delete(tmp);\n" "\t}\n", zoom,zoom,offsetx,offsety,octaves,offset,scale,coef ); break; case CPP : return format( "\t{\n" "\t\tTCODHeightMap tmp(HM_WIDTH,HM_HEIGHT);\n" "\t\ttmp.addFbm(noise,%g,%g,%g,%g,%g,%g,%g);\n" "\t\thm->lerp(hm,&tmp,%g);\n" "\t}\n", zoom,zoom,offsetx,offsety,octaves,offset,scale,coef ); break; case PY : return format( " tmp=libtcod.heightmap_new(HM_WIDTH,HM_HEIGHT)\n" " libtcod.heightmap_add_fbm(tmp,noise,%g,%g,%g,%g,%g,%g,%g)\n" " libtcod.heightmap_lerp(hm,tmp,hm,%g)\n" " libtcod.heightmap_delete(tmp)\n", zoom,zoom,offsetx,offsety,octaves,offset,scale,coef ); break; default:break; } return NULL; } void NoiseLerpOperation::runInternal() { TCODHeightMap tmp(HM_WIDTH,HM_HEIGHT); tmp.addFbm(noise,zoom,zoom,offsetx,offsety,octaves,offset,scale); hm->lerp(hm,&tmp,coef); } bool NoiseLerpOperation::addInternal() { needsNoise=true; addFbmDelta += HM_WIDTH; return true; } void noiseLerpValueCbk(Widget *wid, float val, void *data) { NoiseLerpOperation *op=(NoiseLerpOperation *)data; op->coef = val; if ( Operation::list.peek() == op ) { restore(); op->run(); } else { Operation::reseed(); } } void NoiseLerpOperation::createParamUi() { AddFbmOperation::createParamUi(); params->setName(names[NOISELERP]); Slider *slider=new Slider(0,0,8,-1.0f,1.0f,"coef ","Coefficient of the lerp operation"); slider->setCallback(noiseLerpValueCbk,this); params->addWidget(slider); slider->setValue(coef); } // Voronoi VoronoiOperation::VoronoiOperation(int nbPoints, int nbCoef, float *coef) : nbPoints(nbPoints),nbCoef(nbCoef) { type=VORONOI; for (int i=0; i < MIN(MAX_VORONOI_COEF, nbCoef); i++) { this->coef[i]=coef[i]; } for (int i=MIN(MAX_VORONOI_COEF, nbCoef); i < MAX_VORONOI_COEF; i++) { this->coef[i]=0.0f; } for (int i=0; i < MAX_VORONOI_COEF; i++) { coefSlider[i]=NULL; } } const char *VoronoiOperation::getCode(CodeType type) { char coefstr[256]=""; for (int i=0; i< nbCoef; i++ ) { char tmp2[64]; sprintf(tmp2,"%g,",coef[i]); strcat(coefstr,tmp2); } switch(type) { case C : return format( "\t{\n" "\t\tfloat coef[]={%s};\n" "\t\tTCOD_heightmap_t *tmp =TCOD_heightmap_new(HM_WIDTH,HM_HEIGHT);\n" "\t\tTCOD_heightmap_add_voronoi(tmp,%d,%d,coef,rnd);\n" "\t\tTCOD_heightmap_normalize(tmp,0.0f,1.0f);\n" "\t\tTCOD_heightmap_add_hm(hm,tmp,hm);\n" "\t\tTCOD_heightmap_delete(tmp);\n" "\t}\n", coefstr,nbPoints,nbCoef ); break; case CPP : return format( "\t{\n" "\t\tfloat coef[]={%s};\n" "\t\tTCODHeightMap tmp(HM_WIDTH,HM_HEIGHT);\n" "\t\ttmp.addVoronoi(%d,%d,coef,rnd);\n" "\t\ttmp.normalize();\n" "\t\thm->add(hm,&tmp);\n" "\t}\n", coefstr,nbPoints,nbCoef ); break; case PY : return format( " coef=[%s]\n" " tmp =libtcod.heightmap_new(HM_WIDTH,HM_HEIGHT)\n" " libtcod.heightmap_add_voronoi(tmp,%d,%d,coef,rnd)\n" " libtcod.heightmap_normalize(tmp)\n" " libtcod.heightmap_add_hm(hm,tmp,hm)\n" " libtcod.heightmap_delete(tmp)\n", coefstr,nbPoints,nbCoef ); break; default:break; } return NULL; } void VoronoiOperation::runInternal() { TCODHeightMap tmp(HM_WIDTH,HM_HEIGHT); tmp.addVoronoi(nbPoints,nbCoef,coef,rnd); tmp.normalize(); hm->add(hm,&tmp); } bool VoronoiOperation::addInternal() { needsRandom=true; return true; } void voronoiNbPointsValueCbk(Widget *wid, float val, void *data) { VoronoiOperation *op=(VoronoiOperation *)data; op->nbPoints = (int)val; if ( Operation::list.peek() == op ) { restore(); op->run(); } else { Operation::reseed(); } } void voronoiNbCoefValueCbk(Widget *wid, float val, void *data) { VoronoiOperation *op=(VoronoiOperation *)data; op->nbCoef = (int)val; for (int i=0; i < MAX_VORONOI_COEF; i++ ) { if (i < op->nbCoef ) { op->coefSlider[i]->setVisible(true); } else { op->coefSlider[i]->setVisible(false); } } params->computeSize(); if ( Operation::list.peek() == op ) { restore(); op->run(); } else { Operation::reseed(); } } void voronoiCoefValueCbk(Widget *wid, float val, void *data) { VoronoiOperation *op=(VoronoiOperation *)data; int coefnum; for (coefnum=0; coefnum < op->nbCoef; coefnum++ ) { if ( op->coefSlider[coefnum] == wid ) break; } op->coef[coefnum] = val; if ( Operation::list.peek() == op ) { restore(); op->run(); } else { Operation::reseed(); } } void VoronoiOperation::createParamUi() { params->clear(); params->setName(names[VORONOI]); params->setVisible(true); Slider *slider=new Slider(0,0,8,1.0f,50.0f,"nbPoints","Number of Voronoi points"); slider->setCallback(voronoiNbPointsValueCbk,this); params->addWidget(slider); slider->setFormat("%.0f"); slider->setSensitivity(2.0f); slider->setValue((float)nbPoints); slider=new Slider(0,0,8,1.0f,(float)(MAX_VORONOI_COEF-1),"nbCoef ","Number of Voronoi coefficients"); slider->setCallback(voronoiNbCoefValueCbk,this); params->addWidget(slider); slider->setSensitivity(4.0f); slider->setFormat("%.0f"); slider->setValue((float)nbCoef); for (int i=0;i < MAX_VORONOI_COEF; i++ ) { char tmp[64]; sprintf(tmp,"coef[%d] ",i); coefSlider[i]=new Slider(0,0,8,-5.0f,5.0f,tmp,"Coefficient of Voronoi points"); coefSlider[i]->setCallback(voronoiCoefValueCbk,this); params->addWidget(coefSlider[i]); coefSlider[i]->setValue((float)coef[i]); if ( i >= nbCoef ) coefSlider[i]->setVisible(false); } } libtcod-1.6.4+dfsg/samples/hmtool/operation.hpp000066400000000000000000000143101321276576200215520ustar00rootroot00000000000000#define HM_WIDTH 100 #define HM_HEIGHT 80 // functions used by the operations void backup(); void restore(); void addHill(int nbHill, float baseRadius, float radiusVar, float height); // data used by the operations extern TCODHeightMap *hm; extern TCODNoise *noise; extern ToolBar *params; extern ToolBar *history; extern bool isNormalized; extern float addFbmDelta; extern float scaleFbmDelta; extern int smoothKernelSize; extern int smoothKernelDx[9]; extern int smoothKernelDy[9]; extern float smoothKernelWeight[9]; extern TCODRandom *rnd; extern uint32_t seed; extern float mapmin,mapmax; // an abstract elementary operation on the heightmap class Operation { public : enum OpType { NORM, ADDFBM, SCALEFBM, ADDHILL, ADDLEVEL, SMOOTH, RAIN, NOISELERP, VORONOI }; enum CodeType { C, CPP, PY, NB_CODE }; static const char *names[]; static const char *tips[]; OpType type; static TCODList list; // the list of operation applied since the last clear void run(); // run this operation void add(); // run this operation and adds it in the list virtual void createParamUi(); static const char *buildCode(CodeType type); // generate the code corresponding to the list of operations static void clear(); // remove all operation, clear the heightmap static void cancel(); // cancel the last operation static void reseed(); virtual ~Operation() {} protected : friend void historyCbk(Widget *w,void *data); static bool needsRandom; // we need a random number generator static bool needsNoise; // we need a 2D noise static Operation *currentOp; RadioButton *button; // button associated with this operation in history static void addInitCode(CodeType type,const char *code); // add a global variable or a function to the generated code static const char * format(const char *fmt, ...); // helper to format strings virtual void runInternal() =0; // actually execute this operation virtual bool addInternal() =0; // actually add this operation virtual const char *getCode(CodeType type) = 0; // the code corresponding to this operation private : static char *codebuf; // generated code buffer static int bufSize,freeSize; // total size and remaining size of the code buffer static TCODList initCode[NB_CODE]; // list of global vars/functions to add to the generated code static void addCode(const char *code); // add some code to the generated code }; // normalize the heightmap class NormalizeOperation : public Operation { public : NormalizeOperation(float min=0.0f,float max=1.0f) : min(min),max(max) { type=NORM; } virtual ~NormalizeOperation() {} void createParamUi(); float min,max; protected : const char *getCode(CodeType type); void runInternal(); bool addInternal(); }; // add noise to the heightmap class AddFbmOperation : public Operation { public : AddFbmOperation(float zoom,float offsetx,float offsety,float octaves, float scale,float offset) : zoom(zoom), offsetx(offsetx), offsety(offsety), octaves(octaves), scale(scale), offset(offset) { type=ADDFBM; } virtual ~AddFbmOperation() {} void createParamUi(); float zoom,offsetx,offsety,octaves,scale,offset; protected : const char *getCode(CodeType type); void runInternal(); bool addInternal(); }; // scale the heightmap by a noise function class ScaleFbmOperation : public AddFbmOperation { public : ScaleFbmOperation(float zoom,float offsetx,float offsety,float octaves, float scale,float offset) : AddFbmOperation(zoom, offsetx, offsety, octaves,scale, offset) { type=SCALEFBM; } virtual ~ScaleFbmOperation() {} protected : const char *getCode(CodeType type); void runInternal(); bool addInternal(); }; // add a hill to the heightmap class AddHillOperation : public Operation { public : AddHillOperation(int nbHill,float radius,float radiusVar,float height) : nbHill(nbHill),radius(radius),radiusVar(radiusVar),height(height) { type=ADDHILL; } virtual ~AddHillOperation() {} void createParamUi(); int nbHill; float radius,radiusVar,height; protected : const char *getCode(CodeType type); void runInternal(); bool addInternal(); }; // add a scalar to the heightmap class AddLevelOperation : public Operation { public : AddLevelOperation(float level) : level(level) { type=ADDLEVEL; } virtual ~AddLevelOperation() {} void createParamUi(); float level; protected : const char *getCode(CodeType type); void runInternal(); bool addInternal(); }; // smooth a part of the heightmap class SmoothOperation : public Operation { public : SmoothOperation(float minLevel, float maxLevel, int count) : minLevel(minLevel),maxLevel(maxLevel),radius(0.0f),count(count) { type=SMOOTH; } virtual ~SmoothOperation() {} void createParamUi(); float minLevel,maxLevel,radius; int count; protected : const char *getCode(CodeType type); void runInternal(); bool addInternal(); }; // simulate rain erosion class RainErosionOperation : public Operation { public : RainErosionOperation(int nbDrops,float erosionCoef,float sedimentationCoef) : nbDrops(nbDrops),erosionCoef(erosionCoef),sedimentationCoef(sedimentationCoef) { type=RAIN; } virtual ~RainErosionOperation() {} void createParamUi(); int nbDrops; float erosionCoef,sedimentationCoef; protected : const char *getCode(CodeType type); void runInternal(); bool addInternal(); }; // lerp current heightmap with a noise class NoiseLerpOperation : public AddFbmOperation { public : NoiseLerpOperation(float coef,float zoom,float offsetx,float offsety,float octaves, float scale,float offset) : AddFbmOperation(zoom, offsetx, offsety, octaves,scale, offset),coef(coef) { type=NOISELERP; } virtual ~NoiseLerpOperation() {} void createParamUi(); float coef; protected : const char *getCode(CodeType type); void runInternal(); bool addInternal(); }; // add a voronoi diagram #define MAX_VORONOI_COEF 5 class VoronoiOperation : public Operation { public : VoronoiOperation(int nbPoints, int nbCoef, float *coef); virtual ~VoronoiOperation() {} void createParamUi(); int nbPoints; int nbCoef; float coef[MAX_VORONOI_COEF]; protected : friend void voronoiNbCoefValueCbk(Widget *wid, float val, void *data); friend void voronoiCoefValueCbk(Widget *wid, float val, void *data); Slider *coefSlider[MAX_VORONOI_COEF]; const char *getCode(CodeType type); void runInternal(); bool addInternal(); }; libtcod-1.6.4+dfsg/samples/navier/000077500000000000000000000000001321276576200170245ustar00rootroot00000000000000libtcod-1.6.4+dfsg/samples/navier/main.cpp000066400000000000000000000224201321276576200204540ustar00rootroot00000000000000/* * Copyright (c) 2010 Jice * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "main.hpp" // gas simulation // based on Jos Stam, "Real-Time Fluid Dynamics for Games". Proceedings of the Game Developer Conference, March 2003. // http://www.dgp.toronto.edu/people/stam/reality/Research/pub.html #define WIDTH 50 #define HEIGHT 50 #define WIDTHx2 (WIDTH*2) #define HEIGHTx2 (HEIGHT*2) // use square map #define N MIN(WIDTHx2,HEIGHTx2) // store a 2D map in a 1D array #define SIZE (N+2)*(N+2) // convert x,y to array index #define IX(i,j) ((i)+(N+2)*(j)) #define SWAP(x0,x) {float *tmp=x0;x0=x;x=tmp;} // 2D velocity maps (current and previous) float u[SIZE],v[SIZE], u_prev[SIZE], v_prev[SIZE]; // density maps (current and previous) float dens[SIZE], dens_prev[SIZE]; TCODImage img(WIDTHx2,HEIGHTx2); float visc=1E-6f; float diff=1E-5f; float force=40.0f; float source=5000.0f; float stepDelay=0.0f; int playerx=N/4,playery=N/4; // set boundary conditions void set_bnd ( int b, float * x ) { for ( int i=1 ; i<=N ; i++ ) { // west and east walls x[IX(0,i)] = b == 1 ? -x[IX(1,i)] : x[IX(1,i)]; x[IX(N+1,i)] = b == 1 ? -x[IX(N,i)] : x[IX(N,i)]; // boundary doesn't work on north and south walls... // dunno why... x[IX(i,0)] = b == 1 ? -x[IX(i,1)] : x[IX(i,1)]; x[IX(i,N+1)] = b == 1 ? -x[IX(i,N)] : x[IX(i,N)]; } // boundary conditions at corners x[IX(0 ,0 )] = 0.5f*(x[IX(1,0 )]+x[IX(0 ,1)]); x[IX(0 ,N+1)] = 0.5f*(x[IX(1,N+1)]+x[IX(0 ,N )]); x[IX(N+1,0 )] = 0.5f*(x[IX(N,0 )]+x[IX(N+1,1)]); x[IX(N+1,N+1)] = 0.5f*(x[IX(N,N+1)]+x[IX(N+1,N )]); } // update density map according to density sources // x : density map // s : density source map // dt : elapsed time void add_source(float *x, float *s, float dt) { for (int i=0; i < SIZE; i++) { x[i] += dt*s[i]; } } // update density or velocity map for diffusion // b : boundary width // x : current density map // x0 : previous density map // diff : diffusion coef // dt : elapsed time void diffuse( int b, float *x, float *x0, float diff, float dt) { float a = diff*dt*N*N; for (int k=0; k < 20; k++) { for ( int i=1; i <= N; i++ ) { for (int j=1; j<= N; j++) { x[IX(i,j)] = (x0[IX(i,j)] + a*(x[IX(i-1,j)]+x[IX(i+1,j)] +x[IX(i,j-1)]+x[IX(i,j+1)]))/(1+4*a); } } set_bnd(b,x); } } // update density map according to velocity map // b : boundary width // d : current density map // d0 : previous density map // u,v : current velocity map // dt : elapsed time void advect ( int b, float * d, float * d0, float * u, float * v, float dt ) { int i0, j0, i1, j1; float x, y, s0, t0, s1, t1, dt0; dt0 = dt*N; for ( int i=1 ; i<=N ; i++ ) { for ( int j=1 ; j<=N ; j++ ) { x = i-dt0*u[IX(i,j)]; y = j-dt0*v[IX(i,j)]; if (x<0.5) x=0.5; if (x>N+0.5) x=N+ 0.5; i0=(int)x; i1=i0+1; if (y<0.5) y=0.5; if (y>N+0.5) y=N+ 0.5; j0=(int)y; j1=j0+1; s1 = x-i0; s0 = 1-s1; t1 = y-j0; t0 = 1-t1; d[IX(i,j)] = s0*(t0*d0[IX(i0,j0)]+t1*d0[IX(i0,j1)])+ s1*(t0*d0[IX(i1,j0)]+t1*d0[IX(i1,j1)]); } } set_bnd ( b, d ); } void project ( float * u, float * v, float * p, float * div ) { float h = 1.0f/N; for ( int i=1 ; i<=N ; i++ ) { for ( int j=1 ; j<=N ; j++ ) { div[IX(i,j)] = -0.5f*h*(u[IX(i+1,j)]-u[IX(i-1,j)]+ v[IX(i,j+1)]-v[IX(i,j-1)]); p[IX(i,j)] = 0; } } set_bnd ( 0, div ); set_bnd ( 0, p ); for ( int k=0 ; k<20 ; k++ ) { for ( int i=1 ; i<=N ; i++ ) { for ( int j=1 ; j<=N ; j++ ) { p[IX(i,j)] = (div[IX(i,j)]+p[IX(i-1,j)]+p[IX(i+1,j)]+ p[IX(i,j-1)]+p[IX(i,j+1)])/4; } } set_bnd ( 0, p ); } for ( int i=1 ; i<=N ; i++ ) { for ( int j=1 ; j<=N ; j++ ) { u[IX(i,j)] -= 0.5f*(p[IX(i+1,j)]-p[IX(i-1,j)])/h; v[IX(i,j)] -= 0.5f*(p[IX(i,j+1)]-p[IX(i,j-1)])/h; } } set_bnd ( 1, u ); set_bnd ( 2, v ); } // do all three density steps void update_density ( float * x, float * x0, float * u, float * v, float diff, float dt ) { add_source ( x, x0, dt ); SWAP ( x0, x ); diffuse ( 0, x, x0, diff, dt ); SWAP ( x0, x ); advect ( 0, x, x0, u, v, dt ); } void update_velocity( float * u, float * v, float * u0, float * v0, float visc, float dt ) { add_source ( u, u0, dt ); add_source ( v, v0, dt ); SWAP ( u0, u ); diffuse ( 1, u, u0, visc, dt ); SWAP ( v0, v ); diffuse ( 2, v, v0, visc, dt ); project ( u, v, u0, v0 ); SWAP ( u0, u ); SWAP ( v0, v ); advect ( 1, u, u0, u0, v0, dt ); advect ( 2, v, v0, u0, v0, dt ); project ( u, v, u0, v0 ); } void init() { memset(u,0,sizeof(float)*SIZE); memset(v,0,sizeof(float)*SIZE); memset(u_prev,0,sizeof(float)*SIZE); memset(v_prev,0,sizeof(float)*SIZE); for (int i=0;i < SIZE; i++) dens[i]=0.0f; memcpy(dens_prev,dens,sizeof(float)*SIZE); } void get_from_UI ( float * d, float * u, float * v, float elapsed, TCOD_key_t k,TCOD_mouse_t mouse ) { int i,j; float vx=0.0f,vy=0.0f; stepDelay -= elapsed; if ( stepDelay < 0.0f ) { if ( TCODConsole::isKeyPressed(TCODK_UP) && playery > 0 ) { playery--; vy -= force; } if ( TCODConsole::isKeyPressed(TCODK_DOWN) && playery < N/2-1 ) { playery++; vx += force; } if ( TCODConsole::isKeyPressed(TCODK_LEFT) && playerx > 0 ) { playerx--; vx -= force; } if ( TCODConsole::isKeyPressed(TCODK_RIGHT) && playerx < N/2-1 ) { playerx++; vx += force; } stepDelay=0.2f; // move 5 cells per second // try to move smoke when you walk inside it. doesn't seem to work... u[IX(playerx*2,playery*2)] = 5*vx; v[IX(playerx*2,playery*2)] = 5*vy; } for ( i=0 ; iN || j<1 || j>N ) return; if ( mouse.lbutton ) { float dx,dy,l; dx=(float)(mouse.cx-playerx); dy=(float)(mouse.cy-playery); l=sqrtf(dx*dx+dy*dy); if ( l > 0 ) { l = 1.0f/l; dx*=l; dy*=l; u[IX(playerx*2,playery*2)] = force * dx; v[IX(playerx*2,playery*2)] = force * dy; d[IX(playerx*2,playery*2)] = source; } } } void update(float elapsed, TCOD_key_t k, TCOD_mouse_t mouse) { get_from_UI(dens_prev,u_prev,v_prev,elapsed,k,mouse); update_velocity(u,v,u_prev,v_prev,visc,elapsed); update_density(dens,dens_prev,u,v,diff,elapsed); } void render() { static TCODColor deepBlue = TCODColor::darkestFlame; static TCODColor highBlue = TCODColor::lightestYellow; for (int x=0;x <= N; x++) { for (int y=0; y <= N; y++ ) { float coef=(float)(dens[IX(x,y)]/128.0f); coef=CLAMP(0.0f,1.0f,coef); img.putPixel(x,y,TCODColor::lerp(deepBlue,highBlue,coef )); } } img.blit2x(TCODConsole::root,0,0); TCODConsole::root->print(2,HEIGHT-2,"%4d fps", TCODSystem::getFps()); TCODConsole::root->setDefaultForeground(TCODColor::white); TCODConsole::root->putChar(playerx,playery,'@'); } int main (int argc, char *argv[]) { // initialize the game window TCODConsole::initRoot(WIDTH,HEIGHT,"pyromancer flame spell v" VERSION, false,TCOD_RENDERER_SDL); TCODSystem::setFps(25); TCODMouse::showCursor(true); bool endCredits=false; init(); while (! TCODConsole::isWindowClosed()) { TCOD_key_t k; TCOD_mouse_t mouse; TCODSystem::checkForEvent(TCOD_EVENT_KEY|TCOD_EVENT_MOUSE, &k, &mouse); /* v_prev[IX(N/2,0)] = 1.0f; u_prev[IX(N/3,N/3)]=1.0f; dens_prev[IX(N/2,0)] = 128.0f; */ if ( k.vk == TCODK_PRINTSCREEN ) { // screenshot if (! k.pressed ) TCODSystem::saveScreenshot(NULL); k.vk=TCODK_NONE; } else if ( k.lalt && (k.vk == TCODK_ENTER || k.vk == TCODK_KPENTER) ) { // switch fullscreen if (! k.pressed ) TCODConsole::setFullscreen(!TCODConsole::isFullscreen()); k.vk=TCODK_NONE; } // update the game update(TCODSystem::getLastFrameLength(),k,mouse); // render the game screen render(); TCODConsole::root->print(5,49,"Arrows to move, left mouse button to cast"); // render libtcod credits if (! endCredits ) endCredits = TCODConsole::renderCredits(4,4,true); // flush updates to screen TCODConsole::root->flush(); } return 0; } libtcod-1.6.4+dfsg/samples/navier/main.hpp000066400000000000000000000032601321276576200204620ustar00rootroot00000000000000/* * Copyright (c) 2010 Jice * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libtcod.hpp" #define VERSION "0.1.1" // console size #define CON_W 80 #define CON_H 50 #define IN_RECTANGLE(x,y,w,h) ((unsigned)(x) < (unsigned)(w) && (unsigned)(y) < (unsigned)(h)) #define SQRDIST(x1,y1,x2,y2) (((x1)-(x2))*((x1)-(x2))+((y1)-(y2))*((y1)-(y2))) libtcod-1.6.4+dfsg/samples/rad/000077500000000000000000000000001321276576200163065ustar00rootroot00000000000000libtcod-1.6.4+dfsg/samples/rad/README.txt000066400000000000000000000002661321276576200200100ustar00rootroot00000000000000 Radiosity 0.1.0 “Radiosity” engine Simple light diffusion using some sort of radiosity algorithm Not fast, not clean code… To be improved http://doryen.eptalys.net/demos/ libtcod-1.6.4+dfsg/samples/rad/bsp_helper.cpp000066400000000000000000000146701321276576200211450ustar00rootroot00000000000000/* * Umbra * Copyright (c) 2009, 2010 Mingos, Jice * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The names of Mingos or Jice may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY MINGOS & JICE ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL MINGOS OR JICE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libtcod.hpp" #include "bsp_helper.hpp" BspHelper::BspHelper() { bspDepth=8; minRoomSize=4; randomRoom=true; roomWalls=false; } // draw a vertical line void BspHelper::vline(TCODMap *map,int x, int y1, int y2) { int y=y1; int dy=(y1>y2?-1:1); map->setProperties(x,y,true,true); if ( y1 == y2 ) return; do { y+=dy; map->setProperties(x,y,true,true); } while (y!=y2); } // draw a vertical line up until we reach an empty space void BspHelper::vline_up(TCODMap *map,int x, int y) { while (y >= 0 && !map->isTransparent(x,y)) { map->setProperties(x,y,true,true); y--; } } // draw a vertical line down until we reach an empty space void BspHelper::vline_down(TCODMap *map,int x, int y) { while (y < map->getHeight() && !map->isTransparent(x,y)) { map->setProperties(x,y,true,true); y++; } } // draw a horizontal line void BspHelper::hline(TCODMap *map,int x1, int y, int x2) { int x=x1; int dx=(x1>x2?-1:1); map->setProperties(x,y,true,true); if ( x1 == x2 ) return; do { x+=dx; map->setProperties(x,y,true,true); } while (x!=x2); } // draw a horizontal line left until we reach an empty space void BspHelper::hline_left(TCODMap *map,int x, int y) { while (x >= 0 && !map->isTransparent(x,y)) { map->setProperties(x,y,true,true); x--; } } // draw a horizontal line right until we reach an empty space void BspHelper::hline_right(TCODMap *map,int x, int y) { while (x < map->getWidth() && !map->isTransparent(x,y)) { map->setProperties(x,y,true,true); x++; } } bool BspHelper::visitNode(TCODBsp *node, void *userData) { TCODMap *map=(TCODMap *)userData; if ( node->isLeaf() ) { // calculate the room size int minx = node->x+1; int maxx = node->x+node->w-1; int miny = node->y+1; int maxy = node->y+node->h-1; if (! roomWalls ) { if ( minx > 1 ) minx--; if ( miny > 1 ) miny--; } if (maxx == map->getWidth()-1 ) maxx--; if (maxy == map->getHeight()-1 ) maxy--; if ( randomRoom ) { minx = TCODRandom::getInstance()->getInt(minx,maxx-minRoomSize+1); miny = TCODRandom::getInstance()->getInt(miny,maxy-minRoomSize+1); maxx = TCODRandom::getInstance()->getInt(minx+minRoomSize-1,maxx); maxy = TCODRandom::getInstance()->getInt(miny+minRoomSize-1,maxy); } // keep walls on the map borders minx=MAX(1,minx); miny=MAX(1,miny); maxx=MIN(map->getWidth()-2,maxx); maxy=MIN(map->getHeight()-2,maxy); // resize the node to fit the room //printf("node %dx%d %dx%d => room %dx%d %dx%d\n",node->x,node->y,node->w,node->h,minx,miny,maxx-minx+1,maxy-miny+1); node->x=minx; node->y=miny; node->w=maxx-minx+1; node->h=maxy-miny+1; // dig the room for (int x=minx; x <= maxx; x++ ) { for (int y=miny; y <= maxy; y++ ) { map->setProperties(x,y,true,true); } } } else { //printf("lvl %d %dx%d %dx%d\n",node->level, node->x,node->y,node->w,node->h); // resize the node to fit its sons TCODBsp *left=node->getLeft(); TCODBsp *right=node->getRight(); node->x=MIN(left->x,right->x); node->y=MIN(left->y,right->y); node->w=MAX(left->x+left->w,right->x+right->w)-node->x; node->h=MAX(left->y+left->h,right->y+right->h)-node->y; // create a corridor between the two lower nodes if (node->horizontal) { // vertical corridor if ( left->x+left->w -1 < right->x || right->x+right->w-1 < left->x ) { // no overlapping zone. we need a Z shaped corridor int x1=TCODRandom::getInstance()->getInt(left->x,left->x+left->w-1); int x2=TCODRandom::getInstance()->getInt(right->x,right->x+right->w-1); int y=TCODRandom::getInstance()->getInt(left->y+left->h,right->y); vline_up(map,x1,y-1); hline(map,x1,y,x2); vline_down(map,x2,y+1); } else { // straight vertical corridor int minx=MAX(left->x,right->x); int maxx=MIN(left->x+left->w-1,right->x+right->w-1); int x=TCODRandom::getInstance()->getInt(minx,maxx); vline_down(map,x,right->y); vline_up(map,x,right->y-1); } } else { // horizontal corridor if ( left->y+left->h -1 < right->y || right->y+right->h-1 < left->y ) { // no overlapping zone. we need a Z shaped corridor int y1=TCODRandom::getInstance()->getInt(left->y,left->y+left->h-1); int y2=TCODRandom::getInstance()->getInt(right->y,right->y+right->h-1); int x=TCODRandom::getInstance()->getInt(left->x+left->w,right->x); hline_left(map,x-1,y1); vline(map,x,y1,y2); hline_right(map,x+1,y2); } else { // straight horizontal corridor int miny=MAX(left->y,right->y); int maxy=MIN(left->y+left->h-1,right->y+right->h-1); int y=TCODRandom::getInstance()->getInt(miny,maxy); hline_left(map,right->x-1,y); hline_right(map,right->x,y); } } } return true; } void BspHelper::createBspDungeon(TCODMap *map, TCODRandom *rng) { TCODBsp *bsp = new TCODBsp(0,0,map->getWidth(),map->getHeight()); map->clear(false,false); // fill with walls // create the BSP tree bsp->splitRecursive(rng,bspDepth,minRoomSize+(roomWalls?1:0),minRoomSize+(roomWalls?1:0),1.5f,1.5f); // carve rooms and corridors bsp->traverseInvertedLevelOrder(this,map); } libtcod-1.6.4+dfsg/samples/rad/bsp_helper.hpp000066400000000000000000000040071321276576200211430ustar00rootroot00000000000000/* * Umbra * Copyright (c) 2009, 2010 Mingos, Jice * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The names of Mingos or Jice may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY MINGOS & JICE ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL MINGOS OR JICE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ class BspHelper : public ITCODBspCallback { public : BspHelper(); int bspDepth; int minRoomSize; bool randomRoom; bool roomWalls; void createBspDungeon(TCODMap *map, TCODRandom *rng); // libtcod bsp callback stuff bool visitNode(TCODBsp *node, void *userData); private : void vline(TCODMap *map,int x, int y1, int y2); void vline_up(TCODMap *map,int x, int y); void vline_down(TCODMap *map,int x, int y); void hline(TCODMap *map,int x1, int y, int x2); void hline_left(TCODMap *map,int x, int y); void hline_right(TCODMap *map,int x, int y); }; libtcod-1.6.4+dfsg/samples/rad/main.cpp000066400000000000000000000170411321276576200177410ustar00rootroot00000000000000/* * Photon reactor * Copyright (c) 2011 Jice * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The names of Jice may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "libtcod.hpp" #include "bsp_helper.hpp" #include "rad_shader.hpp" #define CON_WIDTH 80 #define CON_HEIGHT 50 #define MAP_WIDTH 39 #define MAP_HEIGHT 50 #define LIGHT_RADIUS 10 #define CELL_REFLECTIVITY 1.5f #define CELL_SELF_ILLUMINATION 0.4f TCODMap *map; BspHelper bsp; int playerx=0,playery=0,playerBack; Shader *leftShader=NULL; Shader *rightShader=NULL; TCODColor darkWall(50,50,150); TCODColor lightWall(130,110,50); TCODColor darkGround(0,0,100); TCODColor lightGround(200,180,50); int torchIndex; float stdTime=0.0f; float radTime=0.0f; float stdLength=0.0f; float radLength=0.0f; int timeSecond; int framesCount=0; // gamma correction lookup table bool enableGammaCorrection=true; int gammaLookup[256]; #define GAMMA (1/2.2f) // find the closest walkable position void findPos(int *x, int *y) { for (; (*x) < MAP_WIDTH; (*x)++) { for (; (*y)< MAP_HEIGHT; (*y)++) { if ( map->isWalkable((*x),(*y)) ) return; } } for (*x=0; (*x) < MAP_WIDTH; (*x)++) { for (*y=0; (*y)< MAP_HEIGHT; (*y)++) { if ( map->isWalkable((*x),(*y)) ) return; } } } void init() { TCODConsole::root->clear(); // build the dungeon map=new TCODMap(MAP_WIDTH,MAP_HEIGHT); bsp.createBspDungeon(map,NULL); // empty map //map->clear(true,true); // create shaders leftShader=new StandardShader(); rightShader=new PhotonShader(CELL_REFLECTIVITY, CELL_SELF_ILLUMINATION, 3); // put random lights for (int i=0; i < 10; i++ ) { int lx=TCODRandom::getInstance()->getInt(1,MAP_WIDTH-2); int ly=TCODRandom::getInstance()->getInt(1,MAP_HEIGHT-2); findPos(&lx,&ly); leftShader->addLight(lx,ly,LIGHT_RADIUS,TCODColor::white); rightShader->addLight(lx,ly,LIGHT_RADIUS,TCODColor::white); TCODConsole::root->setChar(lx,ly,'*'); TCODConsole::root->setChar(lx+CON_WIDTH/2,ly,'*'); } // find a starting position for the player findPos(&playerx,&playery); playerBack=TCODConsole::root->getChar(playerx,playery); TCODConsole::root->setChar(playerx,playery,'@'); TCODConsole::root->setChar(playerx+CON_WIDTH/2,playery,'@'); // add the player's torch torchIndex = leftShader->addLight(playerx,playery,10,TCODColor::white); rightShader->addLight(playerx,playery,LIGHT_RADIUS,TCODColor::white); // init shaders (must be done after adding lights for photon shader) leftShader->init(map); rightShader->init(map); timeSecond=TCODSystem::getElapsedMilli()/1000; if (enableGammaCorrection) { for (int i=0; i< 256; i++) { float v=i/255.0f; float correctedV = powf(v,GAMMA); gammaLookup[i] = (int)(correctedV*255); } } else { for (int i=0; i< 256; i++) { gammaLookup[i]=i; } } } void render() { // compute lights framesCount++; uint32_t start=TCODSystem::getElapsedMilli(); leftShader->compute(); uint32_t leftEnd=TCODSystem::getElapsedMilli(); rightShader->compute(); uint32_t rightEnd=TCODSystem::getElapsedMilli(); stdTime+=(leftEnd-start)*0.001f; radTime+=(rightEnd-leftEnd)*0.001f; if ( (int)(start/1000) != timeSecond ) { timeSecond=start/1000; stdLength=stdTime*1000/framesCount; radLength=radTime*1000/framesCount; stdTime=0.0f; radTime=0.0f; framesCount=0; } for (int x=0; x < MAP_WIDTH; x++) { for (int y=0; y < MAP_HEIGHT; y++) { TCODColor darkCol,lightCol; // get the cell dark and lit colors if (map->isWalkable(x,y)) { darkCol=darkGround; lightCol=lightGround; } else { darkCol=darkWall; lightCol=lightWall; } // render left map // hack : for a better look, lights are white and we only use them as // a lerp coefficient between dark and light colors. // a true light model would multiply the light color with the cell color TCODColor leftLight=leftShader->getLightColor(x,y); TCODColor cellLeftCol=TCODColor::lerp(darkCol,lightCol,gammaLookup[leftLight.r]/255.0f); TCODConsole::root->setCharBackground(x,y,cellLeftCol); // render right map TCODColor rightLight=rightShader->getLightColor(x,y); TCODColor cellRightCol=TCODColor::lerp(darkCol,lightCol,gammaLookup[rightLight.r]/255.0f); TCODConsole::root->setCharBackground(x+CON_WIDTH/2,y,cellRightCol); } } TCODConsole::root->print(CON_WIDTH/4,0,"Standard lighting %1.2fms",stdLength); TCODConsole::root->print(3*CON_WIDTH/4,0,"Photon reactor %1.2fms",radLength); } void move(int dx, int dy) { if (map->isWalkable(playerx+dx,playery+dy)) { // restore the previous map char TCODConsole::root->setChar(playerx,playery,playerBack); TCODConsole::root->setChar(playerx+CON_WIDTH/2,playery,playerBack); // move the player playerx+=dx; playery+=dy; playerBack=TCODConsole::root->getChar(playerx,playery); // render the player TCODConsole::root->setChar(playerx,playery,'@'); TCODConsole::root->setChar(playerx+CON_WIDTH/2,playery,'@'); // update the player's torch position leftShader->updateLight(torchIndex,playerx,playery,LIGHT_RADIUS,TCODColor::white); rightShader->updateLight(torchIndex,playerx,playery,LIGHT_RADIUS,TCODColor::white); } } int main() { TCODConsole::initRoot(80,50,"Photon reactor - radiosity engine for roguelikes",false,TCOD_RENDERER_SDL); TCODConsole::root->setAlignment(TCOD_CENTER); TCOD_key_t k = {TCODK_NONE,0}; TCOD_mouse_t mouse; init(); while (! TCODConsole::isWindowClosed()) { render(); TCODConsole::flush(); TCODSystem::checkForEvent((TCOD_event_t)TCOD_EVENT_KEY_PRESS,&k,&mouse); switch(k.vk) { // move with arrows or numpad (2468) case TCODK_KP8 : case TCODK_UP : move(0,-1); break; case TCODK_KP2 : case TCODK_DOWN : move(0,1); break; case TCODK_KP4 : case TCODK_LEFT : move(-1,0); break; case TCODK_KP6 : case TCODK_RIGHT : move(1,0); break; case TCODK_CHAR : switch(k.c) { // move with vi keys (HJKL) or FPS keys (WSAD or ZQSD) case 'q' : case 'Q' : case 'a' : case 'A' : case 'h': case 'H' : move(-1,0);break; case 's' : case 'S' : case 'j': case 'J' : move(0,1);break; case 'z' : case 'Z' : case 'w' : case 'W' : case 'k': case 'K' : move(0,-1);break; case 'd' : case 'D' : case 'l': case 'L' : move(1,0);break; default:break; } break; case TCODK_PRINTSCREEN : TCODSystem::saveScreenshot(NULL); break; default:break; } } return 0; } libtcod-1.6.4+dfsg/samples/rad/rad_shader.cpp000066400000000000000000000040441321276576200211100ustar00rootroot00000000000000/* * Photon reactor * Copyright (c) 2011 Jice * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The names of Jice may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libtcod.hpp" #include "rad_shader.hpp" void Shader::init(TCODMap *map) { this->map=map; int size=map->getWidth()*map->getHeight(); lightmap=new TCODColor[size]; } int Shader::addLight(int x, int y, int radius, const TCODColor &col) { int id=lights.size(); Light l; l.x=x; l.y=y; l.radius=radius; l.col=col; lights.push(l); return id; } void Shader::updateLight(int id, int x, int y, int radius, const TCODColor &col) { Light *l=lights.begin()+id; l->x=x; l->y=y; l->radius=radius; l->col=col; } const TCODColor &Shader::getLightColor(int x, int y) { return lightmap[ x + y * map->getWidth()]; } libtcod-1.6.4+dfsg/samples/rad/rad_shader.hpp000066400000000000000000000066511321276576200211230ustar00rootroot00000000000000/* * Photon reactor * Copyright (c) 2011 Jice * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The names of Jice may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ class Shader { public : virtual ~Shader() {} virtual void init(TCODMap *map); // add a new light. return its ID virtual int addLight(int x, int y, int radius, const TCODColor &col); // update the light with given ID virtual void updateLight(int id, int x, int y, int radius, const TCODColor &col); virtual void compute() = 0; // get the computed light color virtual const TCODColor &getLightColor(int x, int y); protected : struct Light { int x,y,radius; TCODColor col; }; TCODList lights; TCODColor *lightmap; TCODMap *map; }; class StandardShader : public Shader { public : void compute(); }; class PhotonShader : public Shader { public : PhotonShader(float reflectivity, float selfIllumination, int nbPass); void init(TCODMap *map); void compute(); int addLight(int x, int y, int radius, const TCODColor &col); protected : // maximum radius of a light in the map int maxRadius; float reflectivity; float selfIllumination; int nbPass; // array of MAP_WIDTH*MAP_HEIGHT*maxDiameter*maxDiamter form factor coefficients (0-255) // maxDiameter = 2*maxRadius+1 float *ff; // array of MAP_WIDTH*MAP_HEIGHT containing the sum of all affected cells form factors for each cell in the map float *ffSum; // convenient way to store the list of cells with non null incoming light struct Coord { uint16_t x; uint16_t y; Coord() {} Coord(int x, int y) : x(x),y(y){} }; TCODList lightsCoord; // color not limited to 0-255 range struct FColor { float r,g,b; }; struct CellData { // amount of light emitted by this cell for this pass FColor emission; // amount of light incoming from other cells for this pass (including self through self illumination) FColor incoming; // total amount of light on the cell (used to shade the map) FColor outgoing; }; // array of MAP_WIDTH*MAP_HEIGHT CellData CellData *data; void propagate(); void computeFormFactor(int x, int y); void computeLightContribution(int lx, int ly, int lradius, const FColor &lcol, float reflectivity); }; libtcod-1.6.4+dfsg/samples/rad/rad_shader_photon.cpp000066400000000000000000000153441321276576200225040ustar00rootroot00000000000000/* * Photon reactor * Copyright (c) 2011 Jice * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The names of Jice may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libtcod.hpp" #include "rad_shader.hpp" PhotonShader::PhotonShader(float reflectivity, float selfIllumination, int nbPass) : maxRadius(0),reflectivity(reflectivity), selfIllumination(selfIllumination), nbPass(nbPass) { } int PhotonShader::addLight(int x, int y, int radius, const TCODColor &col) { if ( radius > maxRadius ) maxRadius=radius; return Shader::addLight(x,y,radius,col); } void PhotonShader::init(TCODMap *map) { Shader::init(map); int size=map->getWidth()*map->getHeight(); int maxDiameter=2*maxRadius+1; // initialize data ff = new float[size*maxDiameter*maxDiameter]; ffSum=new float[size]; data=new CellData[size]; memset(ff,0,sizeof(float)*size*maxDiameter*maxDiameter); memset(data,0,sizeof(CellData)*size); // compute form factors for (int y=0; y < map->getHeight(); y++ ) { for (int x=0; x < map->getWidth(); x++ ) { computeFormFactor(x,y); } } } // compute form factor of cell x,y relative to all its surrounding cells void PhotonShader::computeFormFactor(int x, int y) { int ominx=x-maxRadius; int ominy=y-maxRadius; int omaxx=x+maxRadius; int omaxy=y+maxRadius; int minx=MAX(ominx,0); int miny=MAX(ominy,0); int maxx=MIN(omaxx,map->getWidth()-1); int maxy=MIN(omaxy,map->getHeight()-1); int maxDiameter=2*maxRadius+1; float *cellFormFactor = ff + (x+y*map->getWidth())*maxDiameter*maxDiameter; map->computeFov(x,y,maxRadius); int squareRad=(maxRadius*maxRadius); //float invRad=1.0/squareRad; double curFfSum=0; float offset = 1.0f/(1.0f+(float)(maxRadius*maxRadius)/20); float factor = 1.0f/(1.0f-offset); for (int cx=minx,cdx=minx - ominx; cx<=maxx;cx++,cdx++) { for (int cy=miny,cdy=miny - ominy;cy<=maxy;cy++,cdy++) { if (map->isInFov(cx,cy)) { int dist=(maxRadius-cdx)*(maxRadius-cdx)+(maxRadius-cdy)*(maxRadius-cdy); if ( dist <= squareRad) { //float value = (1.0f-dist*invRad) ; //float value =1.0f/(1.0f+(float)(dist)/20); float value=(1.0f/(1.0f+(float)(dist)/20)- offset)*factor; curFfSum+=value; cellFormFactor[cdx+cdy*maxDiameter]=value; } } } } // scale so that the sum of all form factors for cell x,y is 1.0 ffSum[x+y*map->getWidth()]=(float)curFfSum; if ( curFfSum > 1E-8 ) { curFfSum = 1.0/curFfSum; for (int cx=minx,cdx=minx - ominx; cx<=maxx;cx++,cdx++) { for (int cy=miny,cdy=miny - ominy;cy<=maxy;cy++,cdy++) { cellFormFactor[cdx+cdy*maxDiameter] *= (float)curFfSum; } } } } void PhotonShader::computeLightContribution(int lx, int ly, int lradius, const FColor &lcol, float reflectivity) { int ominx=lx-lradius; int ominy=ly-lradius; int omaxx=lx+lradius; int omaxy=ly+lradius; int minx=MAX(ominx,0); int miny=MAX(ominy,0); int maxx=MIN(omaxx,map->getWidth()-1); int maxy=MIN(omaxy,map->getHeight()-1); int maxDiameter=2*maxRadius+1; float *cellFormFactor = ff + (lx+ly*map->getWidth())*maxDiameter*maxDiameter; // compute the light's contribution #define MIN_FACTOR (1.0f/255.0f) int width=map->getWidth(); for (int y=miny,cdy=miny-ominy; y <= maxy; y++,cdy++) { CellData *cellData=&data[minx+y*width]; float *cellFormRow=&cellFormFactor[minx-ominx+cdy*maxDiameter]; for (int x=minx; x <= maxx; x++,cellData++,cellFormRow++) { float cellff=*cellFormRow; if ( cellff > MIN_FACTOR ) { cellData->incoming.r += lcol.r*cellff; cellData->incoming.g += lcol.g*cellff; cellData->incoming.b += lcol.b*cellff; } } } } void PhotonShader::propagate() { CellData *cellData=data; int size=map->getWidth()*map->getHeight(); lightsCoord.clear(); for (int c=0; c < size; c++,cellData++) { cellData->emission.r=cellData->incoming.r*reflectivity; cellData->emission.g=cellData->incoming.g*reflectivity; cellData->emission.b=cellData->incoming.b*reflectivity; cellData->outgoing.r+=cellData->incoming.r*selfIllumination; cellData->outgoing.g+=cellData->incoming.g*selfIllumination; cellData->outgoing.b+=cellData->incoming.b*selfIllumination; cellData->incoming.r=0; cellData->incoming.g=0; cellData->incoming.b=0; if ( cellData->emission.r> 0 || cellData->emission.g>0 || cellData->emission.b>0) lightsCoord.push(Coord(c%map->getWidth(),c/map->getWidth())); } } void PhotonShader::compute() { // turn off all lights int size=map->getWidth()*map->getHeight(); memset(data,0,sizeof(CellData)*size); // first pass. lights only for ( Light *l=lights.begin(); l != lights.end(); l++) { int off=l->x+l->y*map->getWidth(); CellData *cellData=&data[off]; float sum=ffSum[off]; cellData->emission.r=l->col.r*sum; cellData->emission.g=l->col.r*sum; cellData->emission.b=l->col.r*sum; computeLightContribution(l->x,l->y,l->radius,cellData->emission,0.5f); } // other passes. all lit cells act as lights int pass=1; while ( pass < nbPass ) { propagate(); CellData *cellData=data; //for (int y=0; y < map->getHeight(); y++ ) { // for (int x=0; x < map->getWidth(); x++, cellData++ ) { for ( Coord *c=lightsCoord.begin(); c!=lightsCoord.end(); c++) { cellData=&data[c->x+c->y*map->getWidth()]; computeLightContribution(c->x,c->y,maxRadius,cellData->emission, reflectivity); } pass++; } CellData *cellData=data; TCODColor *col=lightmap; propagate(); for (int c=0; c < size; c++,cellData++, col++) { col->r = (uint8_t)MIN(255,cellData->outgoing.r); col->g = (uint8_t)MIN(255,cellData->outgoing.g); col->b = (uint8_t)MIN(255,cellData->outgoing.b); } } libtcod-1.6.4+dfsg/samples/rad/rad_shader_standard.cpp000066400000000000000000000056251321276576200227760ustar00rootroot00000000000000/* * Photon reactor * Copyright (c) 2011 Jice * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The names of Jice may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libtcod.hpp" #include "rad_shader.hpp" void StandardShader::compute() { // turn off all lights memset(lightmap,0,sizeof(TCODColor)*map->getWidth()*map->getHeight()); for ( Light *l=lights.begin(); l != lights.end(); l++) { // compute the potential visible set for this light int minx=l->x-l->radius; int miny=l->y-l->radius; int maxx=l->x+l->radius; int maxy=l->y+l->radius; minx=MAX(0,minx); miny=MAX(0,miny); maxx=MIN(maxx,map->getWidth()-1); maxy=MIN(maxy,map->getHeight()-1); float offset = 1.0f/(1.0f+(float)(l->radius*l->radius)/20); float factor = 1.0f/(1.0f-offset); // compute the light's fov TCODMap lmap(maxx-minx+1,maxy-miny+1); for (int x=minx; x <= maxx; x++) { for (int y=miny; y <= maxy; y++) { lmap.setProperties(x-minx,y-miny,map->isWalkable(x,y),map->isTransparent(x,y)); } } lmap.computeFov(l->x-minx,l->y-miny,l->radius); // compute the light's contribution //double invSquaredRadius=1.0 / (l->radius*l->radius); for (int x=minx; x <= maxx; x++) { for (int y=miny; y <= maxy; y++) { if ( lmap.isInFov(x-minx,y-miny)) { int squaredDist = (l->x-x)*(l->x-x)+(l->y-y)*(l->y-y); // basic //double coef = 1.0-squaredDist*invSquaredRadius; // invsqr1 //double coef=(1.0f/(1.0f+(float)(squaredDist))); // invsqr2 double coef=(1.0f/(1.0f+(float)(squaredDist)/20)- offset)*factor; TCODColor *col=&lightmap[x+y*map->getWidth()]; *col = *col + l->col * coef; } } } } } libtcod-1.6.4+dfsg/samples/rad/terminal.png000066400000000000000000000065451321276576200206410ustar00rootroot00000000000000PNG  IHDRL\sRGBbKGD pHYs  tIME $#)x IDATx]ˎCЀ ̒  q|Xrجʌr%X*+3Xp\.eYr\.{?5'[DŏroQL=J㿵˴WFO>VQ~NKXeK`u%gap IWFSfU8¼G2o;AYLz7'{#O}#f!(E %^̐9*.af_hߔc;0+CpR-=$,0>~7B2LJ"&AhF/QexK]Tl?)Kk܋/P5SsFT$k6kP}w[ubA!E T2FA1;@`1?4M 4=߉\LZ(`ݢbFzDqv_9:|(XU\h(.q35&\!VLA N`G-BJ#Ǐ d,x$"LAAV[s5/FU3y[[0,K,EDX&a#h|?= O̺ץDXz@U= ? h  -29ޮR2B #>W{ÌHY|l.t=-hSS6~\\炈i; rI)3[qj a=gsԔ. #7WrzNyH#OE\t=PrRԚu(QeШpd=`]x~oEAP?L◳bո*r"֨qrgIF1VUL$r >D:,Յf&v' nmQA(Oh$J5 b\b @qZ)Jeh6">$&d7TA R TRG|`u҆g8}Zh * hUNV/NfC[b[~NU2!4| yU=eR80c _"VG52wRйi0R5L~`T%]VqF4Zn C y͈=4AYfRxNg+?DRHd$˨oŹVXR#Fb+^$4TBG%$:?Q) 0bDU!)DSTXY!`ì}vav>d9)!|g<ҫRd8\SE|E5 iUQP_]n*~,$ث}Jh2LyzU靳]-RS9Y1La*HT)J8ܱn9wAbzbNlABxfjܩה¹S3brgWƓ-6N) Q՞P6Vꏇ_ym_d_崬Q4 86\S׆'ʬwIkHgfwv9/qd&\[*\*ZfdI|f=G{~_g;]֞(=`j)Lfpy_L_wvS;r^)WsZ5‚W.~7ǿ Xt\}^ox QjDiI}(;}fO|^;{}\kNKph0*5.,v~b?؋;Ζ/E4_\qQ j7v_>O-cIENDB`libtcod-1.6.4+dfsg/samples/ripples/000077500000000000000000000000001321276576200172165ustar00rootroot00000000000000libtcod-1.6.4+dfsg/samples/ripples/main.cpp000066400000000000000000000110231321276576200206430ustar00rootroot00000000000000/* * Copyright (c) 2010 Jice * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "main.hpp" TCODNoise noise2d(2); TCODNoise noise3d(3); RippleManager *rippleManager; TCODImage *ground, *ground2; TCODColor mapGradient[256]; #define MAX_COLOR_KEY 8 // TCOD's land color map float sandHeight=0.3f; float grassHeight=0.5f; float snowHeight=0.9f; static int keyIndex[MAX_COLOR_KEY] = {0, (int)(sandHeight*255), (int)(sandHeight*255)+4, (int)(grassHeight*255), (int)(grassHeight*255)+10, (int)(snowHeight*255), (int)(snowHeight*255)+10, 255 }; static TCODColor keyColor[MAX_COLOR_KEY]= { TCODColor(10,10,90), // deep water TCODColor(30,30,170), // water-sand transition TCODColor(114,150,71),// sand TCODColor(80,120,10),// sand-grass transition TCODColor(17,109,7), // grass TCODColor(120,220,120), // grass-snow transisiton TCODColor(208,208,239), // snow TCODColor(255,255,255) }; void update(float elapsed, TCOD_key_t k, TCOD_mouse_t mouse) { if ( mouse.lbutton ) rippleManager->startRipple(mouse.cx*2,mouse.cy*2); rippleManager->updateRipples(elapsed); } void render() { // copy ground into ground2. damn libtcod should have that... for (int x=0; x < CON_W*2;x++) { for (int y=0; y < CON_H*2;y++) { ground2->putPixel(x,y,ground->getPixel(x,y)); } } rippleManager->renderRipples(ground,ground2); ground2->blit2x(TCODConsole::root,0,0); TCODConsole::root->setDefaultForeground(TCODColor::white); TCODConsole::root->print(3,49,"Click in water to trigger ripples"); } int main (int argc, char *argv[]) { // initialize the game window TCODConsole::initRoot(CON_W,CON_H,"Water ripples v" VERSION, false,TCOD_RENDERER_SDL); TCODSystem::setFps(25); TCODMouse::showCursor(true); bool endCredits=false; // create a 2d noise TCODHeightMap hm(CON_W*2,CON_H*2); hm.addFbm(&noise2d,3.0f,3.0f,0,0,7.0f,1.0f,0.5f); hm.normalize(); // apply a color map to create a ground image TCODColor::genMap(mapGradient,MAX_COLOR_KEY,keyColor,keyIndex); ground=new TCODImage(CON_W*2,CON_H*2); ground2=new TCODImage(CON_W*2,CON_H*2); // create a TCODMap defining water zones. Walkable = water TCODMap waterMap(CON_W*2,CON_H*2); for (int x=0; x < CON_W*2;x++) { for (int y=0; y < CON_H*2;y++) { float h=hm.getValue(x,y); bool isWater=h < sandHeight; waterMap.setProperties(x,y,isWater,isWater); int ih=(int)(h*256); ih=CLAMP(0,255,ih); ground->putPixel(x,y,mapGradient[ih]); } } rippleManager = new RippleManager(&waterMap); while (! TCODConsole::isWindowClosed()) { TCOD_key_t k; TCOD_mouse_t mouse; TCODSystem::checkForEvent(TCOD_EVENT_KEY|TCOD_EVENT_MOUSE, &k, &mouse); if ( k.vk == TCODK_PRINTSCREEN ) { // screenshot if (! k.pressed ) TCODSystem::saveScreenshot(NULL); k.vk=TCODK_NONE; } else if ( k.lalt && (k.vk == TCODK_ENTER || k.vk == TCODK_KPENTER) ) { // switch fullscreen if (! k.pressed ) TCODConsole::setFullscreen(!TCODConsole::isFullscreen()); k.vk=TCODK_NONE; } // update the game update(TCODSystem::getLastFrameLength(),k,mouse); // render the game screen render(); // render libtcod credits if (! endCredits ) endCredits = TCODConsole::renderCredits(4,4,true); // flush updates to screen TCODConsole::root->flush(); } return 0; } libtcod-1.6.4+dfsg/samples/ripples/main.hpp000066400000000000000000000034511321276576200206560ustar00rootroot00000000000000/* * Copyright (c) 2010 Jice * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libtcod.hpp" #include "util_ripples.hpp" #define VERSION "0.1.0" // console size #define CON_W 80 #define CON_H 50 #define IN_RECTANGLE(x,y,w,h) ((unsigned)(x) < (unsigned)(w) && (unsigned)(y) < (unsigned)(h)) #define SQRDIST(x1,y1,x2,y2) (((x1)-(x2))*((x1)-(x2))+((y1)-(y2))*((y1)-(y2))) #ifndef NDEBUG #define DBG(x) printf x #else #define DBG(x) #endif extern TCODNoise noise3d; libtcod-1.6.4+dfsg/samples/ripples/util_ripples.cpp000066400000000000000000000116051321276576200224400ustar00rootroot00000000000000/* * Copyright (c) 2010 Jice * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY Jice ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL Jice BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include // windows specific inclusion of alloca // all other platforms have alloca in stdlib.h #ifndef alloca #include #endif #include "main.hpp" // dummy height indicating that a cell is not water #define NO_WATER -1000.0f // how much wave energy is lost per second #define DAMPING_COEF 1.3f // wave height below which the water is considered still #define ACTIVE_THRESHOLD 0.02f // height on the triggering ripple #define RIPPLE_TRIGGER 3.0f // how many times ripples are updated per second #define RIPPLE_FPS 10 RippleManager::RippleManager(TCODMap *waterMap) { init(waterMap); } void RippleManager::init(TCODMap *waterMap) { this->width = waterMap->getWidth(); this->height = waterMap->getHeight(); bool *visited = (bool*)alloca(sizeof(bool)*width*height); memset(visited,0,sizeof(bool)*width*height); // first time : compute water zones zone.cumulatedElapsed=0.0f; zone.isActive=false; zone.data = new float[ width*height ]; zone.oldData = new float[ width*height ]; for (int dx=0; dx < width; dx++) { for (int dy=0; dy < height; dy++) { float value = waterMap->isWalkable(dx,dy) ? 0.0f : NO_WATER; // set water height to 0.0, not water cells to -1000 zone.data[dx+dy*width] = value; } } memcpy(zone.oldData,zone.data,sizeof(float)*width * height); } void RippleManager::startRipple(int x, int y) { // look for the water zone int off=x+y*width; if ( zone.data[off] != NO_WATER ) { zone.data[off] = -RIPPLE_TRIGGER; zone.isActive=true; } } bool RippleManager::updateRipples(float elapsed) { bool updated=false; zone.cumulatedElapsed+=elapsed; if ( zone.isActive ) { // update the ripples if ( zone.cumulatedElapsed > 1.0f/RIPPLE_FPS ) { zone.cumulatedElapsed=0.0f; // swap grids float *tmp=zone.data; zone.data=zone.oldData; zone.oldData=tmp; zone.isActive=false; for (int zx2=1; zx2 < width-1; zx2++) { for (int zy2=1; zy2 < height-1; zy2++) { int off = zx2 + zy2 * width; if (zone.data[off] != NO_WATER) { float sum=0.0f; int count=0; // wave smoothing + spreading if ( zone.oldData[off-1] != NO_WATER ) { sum += zone.oldData[off-1]; count++; } if ( zone.oldData[off+1] != NO_WATER ) { sum += zone.oldData[off+1]; count++; } if ( zone.oldData[off-width] != NO_WATER ) { sum += zone.oldData[off-width]; count++; } if ( zone.oldData[off+width] != NO_WATER ) { sum += zone.oldData[off+width]; count++; } sum = sum * 2 / count; zone.data[off] = sum - zone.data[off]; // damping zone.data[off] *= 1.0f-DAMPING_COEF/RIPPLE_FPS; if ( ABS(zone.data[off]) > ACTIVE_THRESHOLD ) { zone.isActive=true; updated=true; } } } } } } return updated; } void RippleManager::renderRipples(const TCODImage *ground, TCODImage *groundWithRipples) { float elCoef=TCODSystem::getElapsedSeconds()*2.0f; for ( int x = 1; x < width-1; x++ ) { for ( int y = 1; y < height-1; y++ ) { if ( getData(x,y) != NO_WATER ) { float xOffset=(getData(x-1,y)-getData(x+1,y)); float yOffset=(getData(x,y-1)-getData(x,y+1)); float f[3]={float(x),float(y),elCoef}; xOffset+=noise3d.get(f, TCOD_NOISE_SIMPLEX)*0.3f; if ( ABS(xOffset) < 250 && ABS(yOffset) < 250 ) { TCODColor col=ground->getPixel(x+(int)(xOffset),y+(int)(yOffset)); col = col + TCODColor::white*xOffset*0.1f; groundWithRipples->putPixel(x,y,col); } } } } } libtcod-1.6.4+dfsg/samples/ripples/util_ripples.hpp000066400000000000000000000040061321276576200224420ustar00rootroot00000000000000/* * Copyright (c) 2010 Jice * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY Jice ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL Jice BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ struct WaterZone { float cumulatedElapsed; // to control the ripples framerate float *data; // water height data after update float *oldData; // water height data before update bool isActive; // not to use CPU is there are no ripples }; class RippleManager { public : RippleManager(TCODMap *waterMap); void startRipple(int dungeonx, int dungeony); bool updateRipples(float elapsed); void renderRipples(const TCODImage *ground, TCODImage *groundWithRipples); protected : int width,height; WaterZone zone; void init(TCODMap *waterMap); float getData(int x, int y) const { return zone.data[x+y*width]; } }; libtcod-1.6.4+dfsg/samples/samples_c.c000066400000000000000000001613601321276576200176610ustar00rootroot00000000000000/* * libtcod C samples * This code demonstrates various usages of libtcod modules * It's in the public domain. */ // uncomment this to disable SDL sample (might cause compilation issues on some systems) //#define NO_SDL_SAMPLE #include /* for NULL */ #include #include #include "libtcod.h" #define _SDL_main_h #include #include /* a sample has a name and a rendering function */ typedef struct { char name[64]; void (*render)(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse); } sample_t; /* sample screen size */ #define SAMPLE_SCREEN_WIDTH 46 #define SAMPLE_SCREEN_HEIGHT 20 /* sample screen position */ #define SAMPLE_SCREEN_X 20 #define SAMPLE_SCREEN_Y 10 /* *************************** * samples rendering functions * ***************************/ /* the offscreen console in which the samples are rendered */ TCOD_console_t sample_console; /* *************************** * true colors sample * ***************************/ void render_colors(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse) { enum { TOPLEFT, TOPRIGHT, BOTTOMLEFT, BOTTOMRIGHT }; static TCOD_color_t cols[4]={{50,40,150},{240,85,5},{50,35,240},{10,200,130}}; /* random corner colors */ static int dirr[4]={1,-1,1,1},dirg[4]={1,-1,-1,1},dirb[4]={1,1,1,-1}; int c,x,y; TCOD_color_t textColor; /* ==== slighty modify the corner colors ==== */ if ( first ) { TCOD_sys_set_fps(0); /* unlimited fps */ TCOD_console_clear(sample_console); } /* ==== slighty modify the corner colors ==== */ for (c=0; c < 4; c++) { /* move each corner color */ int component=TCOD_random_get_int(NULL,0,2); switch (component) { case 0 : cols[c].r+=5*dirr[c]; if ( cols[c].r == 255 ) dirr[c]=-1; else if (cols[c].r==0) dirr[c]=1; break; case 1 : cols[c].g+=5*dirg[c]; if ( cols[c].g == 255 ) dirg[c]=-1; else if (cols[c].g==0) dirg[c]=1; break; case 2 : cols[c].b+=5*dirb[c]; if ( cols[c].b == 255 ) dirb[c]=-1; else if (cols[c].b==0) dirb[c]=1; break; } } /* ==== scan the whole screen, interpolating corner colors ==== */ for (x=0; x < SAMPLE_SCREEN_WIDTH; x++) { float xcoef = (float)(x)/(SAMPLE_SCREEN_WIDTH-1); /* get the current column top and bottom colors */ TCOD_color_t top = TCOD_color_lerp(cols[TOPLEFT], cols[TOPRIGHT],xcoef); TCOD_color_t bottom = TCOD_color_lerp(cols[BOTTOMLEFT], cols[BOTTOMRIGHT],xcoef); for (y=0; y < SAMPLE_SCREEN_HEIGHT; y++) { float ycoef = (float)(y)/(SAMPLE_SCREEN_HEIGHT-1); /* get the current cell color */ TCOD_color_t curColor = TCOD_color_lerp(top,bottom,ycoef); TCOD_console_set_char_background(sample_console,x,y,curColor,TCOD_BKGND_SET); } } /* ==== print the text ==== */ /* get the background color at the text position */ textColor=TCOD_console_get_char_background(sample_console,SAMPLE_SCREEN_WIDTH/2,5); /* and invert it */ textColor.r=255-textColor.r; textColor.g=255-textColor.g; textColor.b=255-textColor.b; TCOD_console_set_default_foreground(sample_console,textColor); /* put random text (for performance tests) */ for (x=0; x < SAMPLE_SCREEN_WIDTH; x++) { for (y=0; y < SAMPLE_SCREEN_HEIGHT; y++) { int c; TCOD_color_t col=TCOD_console_get_char_background(sample_console,x,y); col=TCOD_color_lerp(col,TCOD_black,0.5f); c=TCOD_random_get_int(NULL,'a','z'); TCOD_console_set_default_foreground(sample_console,col); TCOD_console_put_char(sample_console,x,y,c,TCOD_BKGND_NONE); } } /* the background behind the text is slightly darkened using the BKGND_MULTIPLY flag */ TCOD_console_set_default_background(sample_console,TCOD_grey); TCOD_console_print_rect_ex(sample_console,SAMPLE_SCREEN_WIDTH/2,5, SAMPLE_SCREEN_WIDTH-2,SAMPLE_SCREEN_HEIGHT-1,TCOD_BKGND_MULTIPLY,TCOD_CENTER, "The Doryen library uses 24 bits colors, for both background and foreground."); } /* *************************** * offscreen console sample * ***************************/ void render_offscreen(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse) { static TCOD_console_t secondary; /* second screen */ static TCOD_console_t screenshot; /* second screen */ static bool init=false; /* draw the secondary screen only the first time */ static int counter=0; static int x=0,y=0; /* secondary screen position */ static int xdir=1,ydir=1; /* movement direction */ if (! init ) { init=true; secondary=TCOD_console_new(SAMPLE_SCREEN_WIDTH/2,SAMPLE_SCREEN_HEIGHT/2); screenshot=TCOD_console_new(SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT); TCOD_console_print_frame(secondary,0,0,SAMPLE_SCREEN_WIDTH/2,SAMPLE_SCREEN_HEIGHT/2,false,TCOD_BKGND_SET,"Offscreen console"); TCOD_console_print_rect_ex(secondary,SAMPLE_SCREEN_WIDTH/4,2,SAMPLE_SCREEN_WIDTH/2-2,SAMPLE_SCREEN_HEIGHT/2, TCOD_BKGND_NONE,TCOD_CENTER,"You can render to an offscreen console and blit in on another one, simulating alpha transparency."); } if ( first ) { TCOD_sys_set_fps(30); /* limited to 30 fps */ /* get a "screenshot" of the current sample screen */ TCOD_console_blit(sample_console,0,0,SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT, screenshot,0,0,1.0f,1.0f); } counter++; if ( counter % 20 == 0 ) { /* move the secondary screen every 2 seconds */ x+=xdir;y+=ydir; if ( x == SAMPLE_SCREEN_WIDTH/2+5 ) xdir=-1; else if ( x == -5 ) xdir=1; if ( y == SAMPLE_SCREEN_HEIGHT/2+5 ) ydir=-1; else if ( y == -5 ) ydir=1; } /* restore the initial screen */ TCOD_console_blit(screenshot,0,0,SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT, sample_console,0,0,1.0f,1.0f); /* blit the overlapping screen */ TCOD_console_blit(secondary,0,0,SAMPLE_SCREEN_WIDTH/2,SAMPLE_SCREEN_HEIGHT/2, sample_console,x,y,1.0f,0.75f); } /* *************************** * line drawing sample * ***************************/ static int bk_flag=TCOD_BKGND_SET; /* current blending mode */ bool line_listener(int x, int y) { if ( x>= 0 && y >= 0 && x < SAMPLE_SCREEN_WIDTH && y < SAMPLE_SCREEN_HEIGHT) { TCOD_console_set_char_background(sample_console,x,y,TCOD_light_blue, (TCOD_bkgnd_flag_t)bk_flag); } return true; } void render_lines(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse) { static TCOD_console_t bk; /* colored background */ static bool init=false; static char *flag_names[]={ "TCOD_BKGND_NONE", "TCOD_BKGND_SET", "TCOD_BKGND_MULTIPLY", "TCOD_BKGND_LIGHTEN", "TCOD_BKGND_DARKEN", "TCOD_BKGND_SCREEN", "TCOD_BKGND_COLOR_DODGE", "TCOD_BKGND_COLOR_BURN", "TCOD_BKGND_ADD", "TCOD_BKGND_ADDALPHA", "TCOD_BKGND_BURN", "TCOD_BKGND_OVERLAY", "TCOD_BKGND_ALPHA" }; int xo,yo,xd,yd,x,y; /* segment starting, ending, current position */ float alpha; /* alpha value when blending mode = TCOD_BKGND_ALPHA */ float angle,cos_angle,sin_angle; /* segment angle data */ int recty; /* gradient vertical position */ if ( key->vk == TCODK_ENTER || key->vk == TCODK_KPENTER ) { /* switch to the next blending mode */ bk_flag++; if ( (bk_flag & 0xff) > TCOD_BKGND_ALPH) bk_flag=TCOD_BKGND_NONE; } if ( (bk_flag & 0xff) == TCOD_BKGND_ALPH) { /* for the alpha mode, update alpha every frame */ alpha = (1.0f+cosf(TCOD_sys_elapsed_seconds()*2))/2.0f; bk_flag=TCOD_BKGND_ALPHA(alpha); } else if ( (bk_flag & 0xff) == TCOD_BKGND_ADDA) { /* for the add alpha mode, update alpha every frame */ alpha = (1.0f+cosf(TCOD_sys_elapsed_seconds()*2))/2.0f; bk_flag=TCOD_BKGND_ADDALPHA(alpha); } if (!init) { bk = TCOD_console_new(SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT); /* initialize the colored background */ for (x=0; x < SAMPLE_SCREEN_WIDTH; x ++) { for (y=0; y < SAMPLE_SCREEN_HEIGHT; y++) { TCOD_color_t col; col.r = (uint8_t)(x* 255 / (SAMPLE_SCREEN_WIDTH-1)); col.g = (uint8_t)((x+y)* 255 / (SAMPLE_SCREEN_WIDTH-1+SAMPLE_SCREEN_HEIGHT-1)); col.b = (uint8_t)(y* 255 / (SAMPLE_SCREEN_HEIGHT-1)); TCOD_console_set_char_background(bk,x,y,col,TCOD_BKGND_SET); } } init=true; } if ( first ) { TCOD_sys_set_fps(30); /* limited to 30 fps */ TCOD_console_set_default_foreground(sample_console,TCOD_white); } /* blit the background */ TCOD_console_blit(bk,0,0,SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT,sample_console,0,0,1.0f,1.0f); /* render the gradient */ recty=(int)((SAMPLE_SCREEN_HEIGHT-2)*((1.0f+cosf(TCOD_sys_elapsed_seconds()))/2.0f)); for (x=0;x < SAMPLE_SCREEN_WIDTH; x++) { TCOD_color_t col; col.r=(uint8_t)(x*255/SAMPLE_SCREEN_WIDTH); col.g=(uint8_t)(x*255/SAMPLE_SCREEN_WIDTH); col.b=(uint8_t)(x*255/SAMPLE_SCREEN_WIDTH); TCOD_console_set_char_background(sample_console,x,recty,col,(TCOD_bkgnd_flag_t)bk_flag); TCOD_console_set_char_background(sample_console,x,recty+1,col,(TCOD_bkgnd_flag_t)bk_flag); TCOD_console_set_char_background(sample_console,x,recty+2,col,(TCOD_bkgnd_flag_t)bk_flag); } /* calculate the segment ends */ angle = TCOD_sys_elapsed_seconds()*2.0f; cos_angle=cosf(angle); sin_angle=sinf(angle); xo = (int)(SAMPLE_SCREEN_WIDTH/2*(1 + cos_angle)); yo = (int)(SAMPLE_SCREEN_HEIGHT/2 + sin_angle * SAMPLE_SCREEN_WIDTH/2); xd = (int)(SAMPLE_SCREEN_WIDTH/2*(1 - cos_angle)); yd = (int)(SAMPLE_SCREEN_HEIGHT/2 - sin_angle * SAMPLE_SCREEN_WIDTH/2); /* render the line */ TCOD_line(xo,yo,xd,yd,line_listener); /* print the current flag */ TCOD_console_print(sample_console,2,2,"%s (ENTER to change)",flag_names[bk_flag&0xff]); } /* *************************** * noise sample * ***************************/ void render_noise(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse) { enum { PERLIN,SIMPLEX,WAVELET, FBM_PERLIN,TURBULENCE_PERLIN, FBM_SIMPLEX,TURBULENCE_SIMPLEX, FBM_WAVELET,TURBULENCE_WAVELET }; /* which function we render */ static char *funcName[]={ "1 : perlin noise ", "2 : simplex noise ", "3 : wavelet noise ", "4 : perlin fbm ", "5 : perlin turbulence ", "6 : simplex fbm ", "7 : simplex turbulence ", "8 : wavelet fbm ", "9 : wavelet turbulence ", }; static int func=PERLIN; static TCOD_noise_t noise=NULL; static float dx=0.0f, dy=0.0f; static float octaves=4.0f; static float hurst=TCOD_NOISE_DEFAULT_HURST; static float lacunarity=TCOD_NOISE_DEFAULT_LACUNARITY; static TCOD_image_t img=NULL; static float zoom=3.0f; int x,y,curfunc; if ( !noise) { noise = TCOD_noise_new(2,hurst,lacunarity,NULL); img=TCOD_image_new(SAMPLE_SCREEN_WIDTH*2,SAMPLE_SCREEN_HEIGHT*2); } if ( first ) { TCOD_sys_set_fps(30); /* limited to 30 fps */ } TCOD_console_clear(sample_console); /* texture animation */ dx+=0.01f; dy+=0.01f; /* render the 2d noise function */ for (y=0; y < 2*SAMPLE_SCREEN_HEIGHT; y++ ) { for (x=0; x < 2*SAMPLE_SCREEN_WIDTH; x++ ) { float f[2],value; uint8_t c; TCOD_color_t col; f[0] = zoom*x / (2*SAMPLE_SCREEN_WIDTH) + dx; f[1] = zoom*y / (2*SAMPLE_SCREEN_HEIGHT) + dy; value = 0.0f; switch (func ) { case PERLIN : value = TCOD_noise_get_ex(noise,f,TCOD_NOISE_PERLIN); break; case SIMPLEX : value = TCOD_noise_get_ex(noise,f,TCOD_NOISE_SIMPLEX); break; case WAVELET : value = TCOD_noise_get_ex(noise,f,TCOD_NOISE_WAVELET); break; case FBM_PERLIN : value = TCOD_noise_get_fbm_ex(noise,f,octaves,TCOD_NOISE_PERLIN); break; case TURBULENCE_PERLIN : value = TCOD_noise_get_turbulence_ex(noise,f,octaves,TCOD_NOISE_PERLIN); break; case FBM_SIMPLEX : value = TCOD_noise_get_fbm_ex(noise,f,octaves,TCOD_NOISE_SIMPLEX); break; case TURBULENCE_SIMPLEX : value = TCOD_noise_get_turbulence_ex(noise,f,octaves,TCOD_NOISE_SIMPLEX); break; case FBM_WAVELET : value = TCOD_noise_get_fbm_ex(noise,f,octaves,TCOD_NOISE_WAVELET); break; case TURBULENCE_WAVELET : value = TCOD_noise_get_turbulence_ex(noise,f,octaves,TCOD_NOISE_WAVELET); break; } c=(uint8_t)((value+1.0f)/2.0f*255); /* use a bluish color */ col.r=col.g=c/2; col.b=c; TCOD_image_put_pixel(img,x,y,col); } } /* blit the noise image with subcell resolution */ TCOD_image_blit_2x(img,sample_console,0,0,0,0,-1,-1); /* draw a transparent rectangle */ TCOD_console_set_default_background(sample_console,TCOD_grey); TCOD_console_rect(sample_console,2,2,23,(func <= WAVELET ? 10 : 13),false,TCOD_BKGND_MULTIPLY); for (y=2; y < 2+(func <= WAVELET ? 10 : 13); y++ ) { for (x=2; x < 2+23; x++ ) { TCOD_color_t col=TCOD_console_get_char_foreground(sample_console,x,y); col = TCOD_color_multiply(col, TCOD_grey); TCOD_console_set_char_foreground(sample_console,x,y,col); } } /* draw the text */ for (curfunc=PERLIN; curfunc <= TURBULENCE_WAVELET; curfunc++) { if ( curfunc == func ) { TCOD_console_set_default_foreground(sample_console,TCOD_white); TCOD_console_set_default_background(sample_console,TCOD_light_blue); TCOD_console_print_ex(sample_console,2,2+curfunc,TCOD_BKGND_SET,TCOD_LEFT,funcName[curfunc]); } else { TCOD_console_set_default_foreground(sample_console,TCOD_grey); TCOD_console_print(sample_console,2,2+curfunc,funcName[curfunc]); } } /* draw parameters */ TCOD_console_set_default_foreground(sample_console,TCOD_white); TCOD_console_print(sample_console,2,11,"Y/H : zoom (%2.1f)",zoom); if ( func > WAVELET ) { TCOD_console_print(sample_console,2,12,"E/D : hurst (%2.1f)",hurst); TCOD_console_print(sample_console,2,13,"R/F : lacunarity (%2.1f)",lacunarity); TCOD_console_print(sample_console,2,14,"T/G : octaves (%2.1f)",octaves); } /* handle keypress */ if ( key->vk == TCODK_NONE) return; if (key->vk == TCODK_TEXT && key->text[0] != '\0') { if (key->text[0] >= '1' && key->text[0] <= '9') { /* change the noise function */ func = key->text[0] - '1'; } else if (key->text[0] == 'E' || key->text[0] == 'e') { /* increase hurst */ hurst += 0.1f; TCOD_noise_delete(noise); noise = TCOD_noise_new(2, hurst, lacunarity, NULL); } else if (key->text[0] == 'D' || key->text[0] == 'd') { /* decrease hurst */ hurst -= 0.1f; TCOD_noise_delete(noise); noise = TCOD_noise_new(2, hurst, lacunarity, NULL); } else if (key->text[0] == 'R' || key->text[0] == 'r') { /* increase lacunarity */ lacunarity += 0.5f; TCOD_noise_delete(noise); noise = TCOD_noise_new(2, hurst, lacunarity, NULL); } else if (key->text[0] == 'F' || key->text[0] == 'f') { /* decrease lacunarity */ lacunarity -= 0.5f; TCOD_noise_delete(noise); noise = TCOD_noise_new(2, hurst, lacunarity, NULL); } else if (key->text[0] == 'T' || key->text[0] == 't') { /* increase octaves */ octaves += 0.5f; } else if (key->text[0] == 'G' || key->text[0] == 'g') { /* decrease octaves */ octaves -= 0.5f; } else if (key->text[0] == 'Y' || key->text[0] == 'y') { /* increase zoom */ zoom += 0.2f; } else if (key->text[0] == 'H' || key->text[0] == 'h') { /* decrease zoom */ zoom -= 0.2f; } } } /* *************************** * fov sample * ***************************/ void render_fov(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse) { static char *smap[] = { "##############################################", "####################### #################", "##################### # ###############", "###################### ### ###########", "################## ##### ####", "################ ######## ###### ####", "############### #################### ####", "################ ###### ##", "######## ####### ###### # # # ##", "######## ###### ### ##", "######## ##", "#### ###### ### # # # ##", "#### ### ########## #### ##", "#### ### ########## ###########=##########", "#### ################## ##### #####", "#### ### #### ##### #####", "#### # #### #####", "######## # #### ##### #####", "######## ##### ####################", "##############################################", }; #define TORCH_RADIUS 10.0f #define SQUARED_TORCH_RADIUS (TORCH_RADIUS*TORCH_RADIUS) static int px=20,py=10; /* player position */ static bool recompute_fov=true; static bool torch=false; static bool light_walls=true; static TCOD_map_t map=NULL; static TCOD_color_t dark_wall={0,0,100}; static TCOD_color_t light_wall={130,110,50}; static TCOD_color_t dark_ground={50,50,150}; static TCOD_color_t light_ground={200,180,50}; static TCOD_noise_t noise; static int algonum=0; static char *algo_names[]={"BASIC ", "DIAMOND ", "SHADOW ", "PERMISSIVE0","PERMISSIVE1","PERMISSIVE2","PERMISSIVE3","PERMISSIVE4", "PERMISSIVE5","PERMISSIVE6","PERMISSIVE7","PERMISSIVE8", "RESTRICTIVE"}; static float torchx=0.0f; /* torch light position in the perlin noise */ int x,y; /* torch position & intensity variation */ float dx=0.0f,dy=0.0f,di=0.0f; if ( ! map) { map = TCOD_map_new(SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT); for (y=0; y < SAMPLE_SCREEN_HEIGHT; y++ ) { for (x=0; x < SAMPLE_SCREEN_WIDTH; x++ ) { if ( smap[y][x] == ' ' ) TCOD_map_set_properties(map,x,y,true,true); /* ground */ else if ( smap[y][x] == '=' ) TCOD_map_set_properties(map,x,y,true,false); /* window */ } } noise=TCOD_noise_new(1,1.0f,1.0f,NULL); /* 1d noise for the torch flickering */ } if ( first ) { TCOD_sys_set_fps(30); /* limited to 30 fps */ /* we draw the foreground only the first time. during the player movement, only the @ is redrawn. the rest impacts only the background color */ /* draw the help text & player @ */ TCOD_console_clear(sample_console); TCOD_console_set_default_foreground(sample_console,TCOD_white); TCOD_console_print(sample_console,1,0,"IJKL : move around\nT : torch fx %s\nW : light walls %s\n+-: algo %s", torch ? "on " : "off", light_walls ? "on " : "off", algo_names[algonum]); TCOD_console_set_default_foreground(sample_console,TCOD_black); TCOD_console_put_char(sample_console,px,py,'@',TCOD_BKGND_NONE); /* draw windows */ for (y=0; y < SAMPLE_SCREEN_HEIGHT; y++ ) { for (x=0; x < SAMPLE_SCREEN_WIDTH; x++ ) { if ( smap[y][x] == '=' ) { TCOD_console_put_char(sample_console,x,y,TCOD_CHAR_DHLINE,TCOD_BKGND_NONE); } } } } if ( recompute_fov ) { recompute_fov=false; TCOD_map_compute_fov(map,px,py,torch ? (int)(TORCH_RADIUS) : 0, light_walls, (TCOD_fov_algorithm_t)algonum); } if ( torch ) { float tdx; /* slightly change the perlin noise parameter */ torchx+=0.2f; /* randomize the light position between -1.5 and 1.5 */ tdx=torchx+20.0f; dx = TCOD_noise_get(noise,&tdx)*1.5f; tdx += 30.0f; dy = TCOD_noise_get(noise,&tdx)*1.5f; di = 0.2f * TCOD_noise_get(noise,&torchx); } for (y=0; y < SAMPLE_SCREEN_HEIGHT; y++ ) { for (x=0; x < SAMPLE_SCREEN_WIDTH; x++ ) { bool visible = TCOD_map_is_in_fov(map,x,y); bool wall=smap[y][x]=='#'; if (! visible ) { TCOD_console_set_char_background(sample_console,x,y, wall ? dark_wall:dark_ground,TCOD_BKGND_SET); } else { if ( !torch ) { TCOD_console_set_char_background(sample_console,x,y, wall ? light_wall : light_ground, TCOD_BKGND_SET ); } else { TCOD_color_t base=(wall ? dark_wall : dark_ground); TCOD_color_t light=(wall ? light_wall : light_ground); float r=(x-px+dx)*(x-px+dx)+(y-py+dy)*(y-py+dy); /* cell distance to torch (squared) */ if ( r < SQUARED_TORCH_RADIUS ) { float l = (SQUARED_TORCH_RADIUS-r)/SQUARED_TORCH_RADIUS+di; l=CLAMP(0.0f,1.0f,l); base=TCOD_color_lerp(base,light,l); } TCOD_console_set_char_background(sample_console,x,y,base,TCOD_BKGND_SET); } } } } if (key->vk == TCODK_TEXT && key->text[0] != '\0') { if (key->text[0] == 'I' || key->text[0] == 'i') { if (smap[py - 1][px] == ' ') { TCOD_console_put_char(sample_console, px, py, ' ', TCOD_BKGND_NONE); py--; TCOD_console_put_char(sample_console, px, py, '@', TCOD_BKGND_NONE); recompute_fov = true; } } else if (key->text[0] == 'K' || key->text[0] == 'k') { if (smap[py + 1][px] == ' ') { TCOD_console_put_char(sample_console, px, py, ' ', TCOD_BKGND_NONE); py++; TCOD_console_put_char(sample_console, px, py, '@', TCOD_BKGND_NONE); recompute_fov = true; } } else if (key->text[0] == 'J' || key->text[0] == 'j') { if (smap[py][px - 1] == ' ') { TCOD_console_put_char(sample_console, px, py, ' ', TCOD_BKGND_NONE); px--; TCOD_console_put_char(sample_console, px, py, '@', TCOD_BKGND_NONE); recompute_fov = true; } } else if (key->text[0] == 'L' || key->text[0] == 'l') { if (smap[py][px + 1] == ' ') { TCOD_console_put_char(sample_console, px, py, ' ', TCOD_BKGND_NONE); px++; TCOD_console_put_char(sample_console, px, py, '@', TCOD_BKGND_NONE); recompute_fov = true; } } else if (key->text[0] == 'T' || key->text[0] == 't') { torch = !torch; TCOD_console_set_default_foreground(sample_console, TCOD_white); TCOD_console_print(sample_console, 1, 0, "IJKL : move around\nT : torch fx %s\nW : light walls %s\n+-: algo %s", torch ? "on " : "off", light_walls ? "on " : "off", algo_names[algonum]); TCOD_console_set_default_foreground(sample_console, TCOD_black); } else if (key->text[0] == 'W' || key->text[0] == 'w') { light_walls = !light_walls; TCOD_console_set_default_foreground(sample_console, TCOD_white); TCOD_console_print(sample_console, 1, 0, "IJKL : move around\nT : torch fx %s\nW : light walls %s\n+-: algo %s", torch ? "on " : "off", light_walls ? "on " : "off", algo_names[algonum]); TCOD_console_set_default_foreground(sample_console, TCOD_black); recompute_fov = true; } else if (key->text[0] == '+' || key->text[0] == '-') { algonum += key->text[0] == '+' ? 1 : -1; algonum = CLAMP(0, NB_FOV_ALGORITHMS - 1, algonum); TCOD_console_set_default_foreground(sample_console, TCOD_white); TCOD_console_print(sample_console, 1, 0, "IJKL : move around\nT : torch fx %s\nW : light walls %s\n+-: algo %s", torch ? "on " : "off", light_walls ? "on " : "off", algo_names[algonum]); TCOD_console_set_default_foreground(sample_console, TCOD_black); recompute_fov = true; } } } /* *************************** * image sample * ***************************/ void render_image(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse) { static TCOD_image_t img=NULL, circle=NULL; static TCOD_color_t blue={0,0,255}; static TCOD_color_t green={0,255,0}; float x,y,scalex,scaley,angle; long elapsed; if ( img == NULL ) { img=TCOD_image_load("data/img/skull.png"); TCOD_image_set_key_color(img,TCOD_black); circle=TCOD_image_load("data/img/circle.png"); } if ( first ) { TCOD_sys_set_fps(30); /* limited to 30 fps */ } TCOD_console_set_default_background(sample_console,TCOD_black); TCOD_console_clear(sample_console); x=SAMPLE_SCREEN_WIDTH/2+cosf(TCOD_sys_elapsed_seconds())*10.0f; y=(float)(SAMPLE_SCREEN_HEIGHT/2); scalex=0.2f+1.8f*(1.0f+cosf(TCOD_sys_elapsed_seconds()/2))/2.0f; scaley=scalex; angle=TCOD_sys_elapsed_seconds(); elapsed=TCOD_sys_elapsed_milli()/2000; if ( elapsed & 1 ) { /* split the color channels of circle.png */ /* the red channel */ TCOD_console_set_default_background(sample_console,TCOD_red); TCOD_console_rect(sample_console,0,3,15,15,false,TCOD_BKGND_SET); TCOD_image_blit_rect(circle,sample_console,0,3,-1,-1,TCOD_BKGND_MULTIPLY); /* the green channel */ TCOD_console_set_default_background(sample_console,green); TCOD_console_rect(sample_console,15,3,15,15,false,TCOD_BKGND_SET); TCOD_image_blit_rect(circle,sample_console,15,3,-1,-1,TCOD_BKGND_MULTIPLY); /* the blue channel */ TCOD_console_set_default_background(sample_console,blue); TCOD_console_rect(sample_console,30,3,15,15,false,TCOD_BKGND_SET); TCOD_image_blit_rect(circle,sample_console,30,3,-1,-1,TCOD_BKGND_MULTIPLY); } else { /* render circle.png with normal blitting */ TCOD_image_blit_rect(circle,sample_console,0,3,-1,-1,TCOD_BKGND_SET); TCOD_image_blit_rect(circle,sample_console,15,3,-1,-1,TCOD_BKGND_SET); TCOD_image_blit_rect(circle,sample_console,30,3,-1,-1,TCOD_BKGND_SET); } TCOD_image_blit(img,sample_console,x,y, TCOD_BKGND_SET,scalex,scaley,angle); } /* *************************** * mouse sample * ***************************/ void render_mouse(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse) { static bool lbut=false,rbut=false,mbut=false; if ( first ) { TCOD_console_set_default_background(sample_console,TCOD_grey); TCOD_console_set_default_foreground(sample_console,TCOD_light_yellow); TCOD_mouse_move(320,200); TCOD_mouse_show_cursor(true); TCOD_sys_set_fps(30); /* limited to 30 fps */ } TCOD_console_clear(sample_console); if ( mouse->lbutton_pressed ) lbut=!lbut; if ( mouse->rbutton_pressed ) rbut=!rbut; if ( mouse->mbutton_pressed ) mbut=!mbut; TCOD_console_print(sample_console,1,1, "%s\n" "Mouse position : %4dx%4d %s\n" "Mouse cell : %4dx%4d\n" "Mouse movement : %4dx%4d\n" "Left button : %s (toggle %s)\n" "Right button : %s (toggle %s)\n" "Middle button : %s (toggle %s)\n" "Wheel : %s\n", TCOD_console_is_active() ? "" : "APPLICATION INACTIVE", mouse->x,mouse->y,TCOD_console_has_mouse_focus() ? "" : "OUT OF FOCUS", mouse->cx,mouse->cy, mouse->dx,mouse->dy, mouse->lbutton ? " ON" : "OFF",lbut ? " ON" : "OFF", mouse->rbutton ? " ON" : "OFF",rbut ? " ON" : "OFF", mouse->mbutton ? " ON" : "OFF",mbut ? " ON" : "OFF", mouse->wheel_up ? "UP" : (mouse->wheel_down ? "DOWN" : "") ); TCOD_console_print(sample_console,1,10,"1 : Hide cursor\n2 : Show cursor"); if (key->vk == TCODK_TEXT && key->text[0] != '\0') { if (key->text[0] == '1') TCOD_mouse_show_cursor(false); else if (key->text[0] == '2') TCOD_mouse_show_cursor(true); } } /* *************************** * path sample * ***************************/ void render_path(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse) { static const char *smap[] = { "##############################################", "####################### #################", "##################### # ###############", "###################### ### ###########", "################## ##### ####", "################ ######## ###### ####", "############### #################### ####", "################ ###### ##", "######## ####### ###### # # # ##", "######## ###### ### ##", "######## ##", "#### ###### ### # # # ##", "#### ### ########## #### ##", "#### ### ########## ###########=##########", "#### ################## ##### #####", "#### ### #### ##### #####", "#### # #### #####", "######## # #### ##### #####", "######## ##### ####################", "##############################################", }; #define TORCH_RADIUS 10.0f #define SQUARED_TORCH_RADIUS (TORCH_RADIUS*TORCH_RADIUS) static int px=20,py=10; // player position static int dx=24,dy=1; // destination static TCOD_map_t map=NULL; static TCOD_color_t dark_wall={0,0,100}; static TCOD_color_t dark_ground={50,50,150}; static TCOD_color_t light_ground={200,180,50}; static TCOD_path_t path=NULL; static bool usingAstar=true; static float dijkstraDist=0; static TCOD_dijkstra_t *dijkstra = NULL; static bool recalculatePath=false; static float busy; static int oldChar=' '; int mx,my,x,y,i; if ( ! map) { /* initialize the map */ map = TCOD_map_new(SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT); for (y=0; y < SAMPLE_SCREEN_HEIGHT; y++ ) { for (x=0; x < SAMPLE_SCREEN_WIDTH; x++ ) { if ( smap[y][x] == ' ' ) TCOD_map_set_properties(map,x,y,true,true); /* ground */ else if ( smap[y][x] == '=' ) TCOD_map_set_properties(map,x,y,true,false); /* window */ } } path=TCOD_path_new_using_map(map,1.41f); dijkstra=TCOD_dijkstra_new(map,1.41f); } if ( first ) { TCOD_sys_set_fps(30); /* limited to 30 fps */ /* we draw the foreground only the first time. during the player movement, only the @ is redrawn. the rest impacts only the background color */ /* draw the help text & player @ */ TCOD_console_clear(sample_console); TCOD_console_set_default_foreground(sample_console,TCOD_white); TCOD_console_put_char(sample_console,dx,dy,'+',TCOD_BKGND_NONE); TCOD_console_put_char(sample_console,px,py,'@',TCOD_BKGND_NONE); TCOD_console_print(sample_console,1,1,"IJKL / mouse :\nmove destination\nTAB : A*/dijkstra"); TCOD_console_print(sample_console,1,4,"Using : A*"); /* draw windows */ for (y=0; y < SAMPLE_SCREEN_HEIGHT; y++ ) { for (x=0; x < SAMPLE_SCREEN_WIDTH; x++ ) { if ( smap[y][x] == '=' ) { TCOD_console_put_char(sample_console,x,y,TCOD_CHAR_DHLINE,TCOD_BKGND_NONE); } } } recalculatePath=true; } if ( recalculatePath ) { if ( usingAstar ) { TCOD_path_compute(path,px,py,dx,dy); } else { int x,y; dijkstraDist=0.0f; /* compute the distance grid */ TCOD_dijkstra_compute(dijkstra,px,py); /* get the maximum distance (needed for ground shading only) */ for (y=0; y < SAMPLE_SCREEN_HEIGHT; y++ ) { for (x=0; x < SAMPLE_SCREEN_WIDTH; x++ ) { float d= TCOD_dijkstra_get_distance(dijkstra,x,y); if ( d > dijkstraDist ) dijkstraDist=d; } } // compute the path TCOD_dijkstra_path_set(dijkstra,dx,dy); } recalculatePath=false; busy=0.2f; } // draw the dungeon for (y=0; y < SAMPLE_SCREEN_HEIGHT; y++ ) { for (x=0; x < SAMPLE_SCREEN_WIDTH; x++ ) { bool wall=smap[y][x]=='#'; TCOD_console_set_char_background(sample_console,x,y,wall ? dark_wall : dark_ground, TCOD_BKGND_SET ); } } // draw the path if ( usingAstar ) { for (i=0; i< TCOD_path_size(path); i++ ) { int x,y; TCOD_path_get(path,i,&x,&y); TCOD_console_set_char_background(sample_console,x,y,light_ground, TCOD_BKGND_SET ); } } else { int x,y,i; for (y=0; y < SAMPLE_SCREEN_HEIGHT; y++ ) { for (x=0; x < SAMPLE_SCREEN_WIDTH; x++ ) { bool wall=smap[y][x]=='#'; if (! wall) { float d= TCOD_dijkstra_get_distance(dijkstra,x,y); TCOD_console_set_char_background(sample_console,x,y,TCOD_color_lerp(light_ground,dark_ground,0.9f * d / dijkstraDist), TCOD_BKGND_SET ); } } } for (i=0; i< TCOD_dijkstra_size(dijkstra); i++ ) { int x,y; TCOD_dijkstra_get(dijkstra,i,&x,&y); TCOD_console_set_char_background(sample_console,x,y,light_ground, TCOD_BKGND_SET ); } } // move the creature busy-=TCOD_sys_get_last_frame_length(); if (busy <= 0.0f ) { busy = 0.2f; if ( usingAstar ) { if (!TCOD_path_is_empty(path)) { TCOD_console_put_char(sample_console,px,py,' ',TCOD_BKGND_NONE); TCOD_path_walk(path,&px,&py,true); TCOD_console_put_char(sample_console,px,py,'@',TCOD_BKGND_NONE); } } else { if (!TCOD_dijkstra_is_empty(dijkstra)) { TCOD_console_put_char(sample_console,px,py,' ',TCOD_BKGND_NONE); TCOD_dijkstra_path_walk(dijkstra,&px,&py); TCOD_console_put_char(sample_console,px,py,'@',TCOD_BKGND_NONE); recalculatePath=true; } } } if (key->vk == TCODK_TAB) { usingAstar = !usingAstar; if (usingAstar) TCOD_console_print(sample_console, 1, 4, "Using : A* "); else TCOD_console_print(sample_console, 1, 4, "Using : Dijkstra"); recalculatePath = true; } else if (key->vk == TCODK_TEXT && key->text[0] != '\0') { if ((key->text[0] == 'I' || key->text[0] == 'i') && dy > 0) { // destination move north TCOD_console_put_char(sample_console, dx, dy, oldChar, TCOD_BKGND_NONE); dy--; oldChar = TCOD_console_get_char(sample_console, dx, dy); TCOD_console_put_char(sample_console, dx, dy, '+', TCOD_BKGND_NONE); if (smap[dy][dx] == ' ') { recalculatePath = true; } } else if ((key->text[0] == 'K' || key->text[0] == 'k') && dy < SAMPLE_SCREEN_HEIGHT - 1) { // destination move south TCOD_console_put_char(sample_console, dx, dy, oldChar, TCOD_BKGND_NONE); dy++; oldChar = TCOD_console_get_char(sample_console, dx, dy); TCOD_console_put_char(sample_console, dx, dy, '+', TCOD_BKGND_NONE); if (smap[dy][dx] == ' ') { recalculatePath = true; } } else if ((key->text[0] == 'J' || key->text[0] == 'j') && dx > 0) { // destination move west TCOD_console_put_char(sample_console, dx, dy, oldChar, TCOD_BKGND_NONE); dx--; oldChar = TCOD_console_get_char(sample_console, dx, dy); TCOD_console_put_char(sample_console, dx, dy, '+', TCOD_BKGND_NONE); if (smap[dy][dx] == ' ') { recalculatePath = true; } } else if ((key->text[0] == 'L' || key->text[0] == 'l') && dx < SAMPLE_SCREEN_WIDTH - 1) { // destination move east TCOD_console_put_char(sample_console, dx, dy, oldChar, TCOD_BKGND_NONE); dx++; oldChar = TCOD_console_get_char(sample_console, dx, dy); TCOD_console_put_char(sample_console, dx, dy, '+', TCOD_BKGND_NONE); if (smap[dy][dx] == ' ') { recalculatePath = true; } } } mx = mouse->cx-SAMPLE_SCREEN_X; my = mouse->cy-SAMPLE_SCREEN_Y; if ( mx >= 0 && mx < SAMPLE_SCREEN_WIDTH && my >= 0 && my < SAMPLE_SCREEN_HEIGHT && ( dx != mx || dy != my ) ) { TCOD_console_put_char(sample_console,dx,dy,oldChar,TCOD_BKGND_NONE); dx=mx;dy=my; oldChar=TCOD_console_get_char(sample_console,dx,dy); TCOD_console_put_char(sample_console,dx,dy,'+',TCOD_BKGND_NONE); if ( smap[dy][dx] == ' ' ) { recalculatePath=true; } } } // *************************** // bsp sample // *************************** static int bspDepth=8; static int minRoomSize=4; static bool randomRoom=false; // a room fills a random part of the node or the maximum available space ? static bool roomWalls=true; // if true, there is always a wall on north & west side of a room typedef char map_t[SAMPLE_SCREEN_WIDTH][SAMPLE_SCREEN_HEIGHT]; // draw a vertical line void vline(map_t *map,int x, int y1, int y2) { int y=y1; int dy=(y1>y2?-1:1); (*map)[x][y]=' '; if ( y1 == y2 ) return; do { y+=dy; (*map)[x][y]=' '; } while (y!=y2); } // draw a vertical line up until we reach an empty space void vline_up(map_t *map,int x, int y) { while (y >= 0 && (*map)[x][y] != ' ') { (*map)[x][y]=' '; y--; } } // draw a vertical line down until we reach an empty space void vline_down(map_t *map,int x, int y) { while (y < SAMPLE_SCREEN_HEIGHT && (*map)[x][y] != ' ') { (*map)[x][y]=' '; y++; } } // draw a horizontal line void hline(map_t *map,int x1, int y, int x2) { int x=x1; int dx=(x1>x2?-1:1); (*map)[x][y]=' '; if ( x1 == x2 ) return; do { x+=dx; (*map)[x][y]=' '; } while (x!=x2); } // draw a horizontal line left until we reach an empty space void hline_left(map_t *map,int x, int y) { while (x >= 0 && (*map)[x][y] != ' ') { (*map)[x][y]=' '; x--; } } // draw a horizontal line right until we reach an empty space void hline_right(map_t *map,int x, int y) { while (x < SAMPLE_SCREEN_WIDTH && (*map)[x][y] != ' ') { (*map)[x][y]=' '; x++; } } // the class building the dungeon from the bsp nodes bool traverse_node(TCOD_bsp_t *node, void *userData) { map_t *map=(map_t *)userData; if ( TCOD_bsp_is_leaf(node) ) { // calculate the room size int minx = node->x+1; int maxx = node->x+node->w-1; int miny = node->y+1; int maxy = node->y+node->h-1; int x,y; if (! roomWalls ) { if ( minx > 1 ) minx--; if ( miny > 1 ) miny--; } if (maxx == SAMPLE_SCREEN_WIDTH-1 ) maxx--; if (maxy == SAMPLE_SCREEN_HEIGHT-1 ) maxy--; if ( randomRoom ) { minx = TCOD_random_get_int(NULL,minx,maxx-minRoomSize+1); miny = TCOD_random_get_int(NULL,miny,maxy-minRoomSize+1); maxx = TCOD_random_get_int(NULL,minx+minRoomSize-1,maxx); maxy = TCOD_random_get_int(NULL,miny+minRoomSize-1,maxy); } // resize the node to fit the room // printf("node %dx%d %dx%d => room %dx%d %dx%d\n",node->x,node->y,node->w,node->h,minx,miny,maxx-minx+1,maxy-miny+1); node->x=minx; node->y=miny; node->w=maxx-minx+1; node->h=maxy-miny+1; // dig the room for (x=minx; x <= maxx; x++ ) { for (y=miny; y <= maxy; y++ ) { (*map)[x][y]=' '; } } } else { // printf("lvl %d %dx%d %dx%d\n",node->level, node->x,node->y,node->w,node->h); // resize the node to fit its sons TCOD_bsp_t *left=TCOD_bsp_left(node); TCOD_bsp_t *right=TCOD_bsp_right(node); node->x=MIN(left->x,right->x); node->y=MIN(left->y,right->y); node->w=MAX(left->x+left->w,right->x+right->w)-node->x; node->h=MAX(left->y+left->h,right->y+right->h)-node->y; // create a corridor between the two lower nodes if (node->horizontal) { // vertical corridor if ( left->x+left->w -1 < right->x || right->x+right->w-1 < left->x ) { // no overlapping zone. we need a Z shaped corridor int x1=TCOD_random_get_int(NULL,left->x,left->x+left->w-1); int x2=TCOD_random_get_int(NULL,right->x,right->x+right->w-1); int y=TCOD_random_get_int(NULL,left->y+left->h,right->y); vline_up(map,x1,y-1); hline(map,x1,y,x2); vline_down(map,x2,y+1); } else { // straight vertical corridor int minx=MAX(left->x,right->x); int maxx=MIN(left->x+left->w-1,right->x+right->w-1); int x=TCOD_random_get_int(NULL,minx,maxx); vline_down(map,x,right->y); vline_up(map,x,right->y-1); } } else { // horizontal corridor if ( left->y+left->h -1 < right->y || right->y+right->h-1 < left->y ) { // no overlapping zone. we need a Z shaped corridor int y1=TCOD_random_get_int(NULL,left->y,left->y+left->h-1); int y2=TCOD_random_get_int(NULL,right->y,right->y+right->h-1); int x=TCOD_random_get_int(NULL,left->x+left->w,right->x); hline_left(map,x-1,y1); vline(map,x,y1,y2); hline_right(map,x+1,y2); } else { // straight horizontal corridor int miny=MAX(left->y,right->y); int maxy=MIN(left->y+left->h-1,right->y+right->h-1); int y=TCOD_random_get_int(NULL,miny,maxy); hline_left(map,right->x-1,y); hline_right(map,right->x,y); } } } return true; } void render_bsp(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse) { static TCOD_bsp_t *bsp=NULL; static bool generate=true; static bool refresh=false; static char map[SAMPLE_SCREEN_WIDTH][SAMPLE_SCREEN_HEIGHT]; static TCOD_color_t darkWall={0,0,100}; static TCOD_color_t darkGround={50,50,150}; int x,y; if ( generate || refresh ) { // dungeon generation if (! bsp ) { // create the bsp bsp = TCOD_bsp_new_with_size(0,0,SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT); } else { // restore the nodes size TCOD_bsp_resize(bsp,0,0,SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT); } memset(map,'#',sizeof(char)*SAMPLE_SCREEN_WIDTH*SAMPLE_SCREEN_HEIGHT); if ( generate ) { // build a new random bsp tree TCOD_bsp_remove_sons(bsp); TCOD_bsp_split_recursive(bsp,NULL,bspDepth,minRoomSize+(roomWalls?1:0),minRoomSize+(roomWalls?1:0),1.5f,1.5f); } // create the dungeon from the bsp TCOD_bsp_traverse_inverted_level_order(bsp,traverse_node,&map); generate=false; refresh=false; } TCOD_console_clear(sample_console); TCOD_console_set_default_foreground(sample_console,TCOD_white); TCOD_console_print(sample_console,1,1,"ENTER : rebuild bsp\nSPACE : rebuild dungeon\n+-: bsp depth %d\n*/: room size %d\n1 : random room size %s", bspDepth,minRoomSize, randomRoom ? "ON" : "OFF"); if ( randomRoom ) TCOD_console_print(sample_console,1,6,"2 : room walls %s", roomWalls ? "ON" : "OFF" ); // render the level for (y=0; y < SAMPLE_SCREEN_HEIGHT; y++ ) { for (x=0; x < SAMPLE_SCREEN_WIDTH; x++ ) { bool wall= ( map[x][y] == '#' ); TCOD_console_set_char_background(sample_console,x,y,wall ? darkWall : darkGround, TCOD_BKGND_SET ); } } if (key->vk == TCODK_ENTER || key->vk == TCODK_KPENTER) { generate = true; } else if (key->vk == TCODK_TEXT && key->text[0] != '\0') { if (key->text[0] == ' ') { refresh = true; } else if (key->text[0] == '+') { bspDepth++; generate = true; } else if (key->text[0] == '-' && bspDepth > 1) { bspDepth--; generate = true; } else if (key->text[0] == '*') { minRoomSize++; generate = true; } else if (key->text[0] == '/' && minRoomSize > 2) { minRoomSize--; generate = true; } else if (key->text[0] == '1' || key->vk == TCODK_1 || key->vk == TCODK_KP1) { randomRoom = !randomRoom; if (!randomRoom) roomWalls = true; refresh = true; } else if (key->text[0] == '2' || key->vk == TCODK_2 || key->vk == TCODK_KP2) { roomWalls = !roomWalls; refresh = true; } } } /* *************************** * name generator sample * ***************************/ void render_name(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse) { static int nbSets; static int curSet=0; static float delay=0.0f; static TCOD_list_t sets=NULL; static TCOD_list_t names=NULL; int i; if ( ! names ) { TCOD_list_t files; char **it; names=TCOD_list_new(); files=TCOD_sys_get_directory_content("data/namegen","*.cfg"); // parse all the files for (it=(char **)TCOD_list_begin(files); it!= (char **)TCOD_list_end(files); it++) { char tmp[236]; sprintf(tmp, "data/namegen/%s",*it); TCOD_namegen_parse(tmp,NULL); } // get the sets list sets=TCOD_namegen_get_sets(); nbSets=TCOD_list_size(sets); } if ( first ) { TCOD_sys_set_fps(30); /* limited to 30 fps */ } while ( TCOD_list_size(names) >= 15 ) { // remove the first element. #ifndef TCOD_VISUAL_STUDIO char *nameToRemove= * (TCOD_list_begin(names)); #endif TCOD_list_remove_iterator(names, TCOD_list_begin(names)); // for some reason, this crashes on MSVC... #ifndef TCOD_VISUAL_STUDIO free(nameToRemove); #endif } TCOD_console_clear(sample_console); TCOD_console_set_default_foreground(sample_console,TCOD_white); if (TCOD_list_size(sets) > 0) { TCOD_console_print(sample_console,1,1,"%s\n\n+ : next generator\n- : prev generator", (char *)TCOD_list_get(sets,curSet)); for (i=0; i < TCOD_list_size(names); i++) { char *name=(char *)TCOD_list_get(names,i); if ( strlen(name)< SAMPLE_SCREEN_WIDTH ) TCOD_console_print_ex(sample_console,SAMPLE_SCREEN_WIDTH-2,2+i, TCOD_BKGND_NONE,TCOD_RIGHT,name); } delay += TCOD_sys_get_last_frame_length(); if ( delay >= 0.5f ) { delay -= 0.5f; // add a new name to the list TCOD_list_push(names, TCOD_namegen_generate((char *)TCOD_list_get(sets,curSet), true)); } if (key->vk == TCODK_TEXT && key->text[0] != '\0') { if (key->text[0] == '+') { curSet++; if (curSet == nbSets) curSet = 0; TCOD_list_push(names, strdup("======")); } else if (key->text[0] == '-') { curSet--; if (curSet < 0) curSet = nbSets - 1; TCOD_list_push(names, strdup("======")); } } } else { TCOD_console_print(sample_console,1,1,"Unable to find name config data files."); } } /* *************************** * SDL callback sample * ***************************/ #ifndef NO_SDL_SAMPLE TCOD_noise_t noise=NULL; bool sdl_callback_enabled=false; int effectNum = 0; float delay = 3.0f; void burn(SDL_Surface *screen, int samplex, int sampley, int samplew, int sampleh) { int ridx=screen->format->Rshift/8; int gidx=screen->format->Gshift/8; int bidx=screen->format->Bshift/8; int x,y; for (x=samplex; x < samplex + samplew; x ++ ) { uint8_t *p = (uint8_t *)screen->pixels + x * screen->format->BytesPerPixel + sampley * screen->pitch; for (y=sampley; y < sampley + sampleh; y ++ ) { int ir=0,ig=0,ib=0; uint8_t *p2 = p + screen->format->BytesPerPixel; // get pixel at x+1,y ir += p2[ridx]; ig += p2[gidx]; ib += p2[bidx]; p2 -= 2*screen->format->BytesPerPixel; // get pixel at x-1,y ir += p2[ridx]; ig += p2[gidx]; ib += p2[bidx]; p2 += screen->format->BytesPerPixel+ screen->pitch; // get pixel at x,y+1 ir += p2[ridx]; ig += p2[gidx]; ib += p2[bidx]; p2 -= 2*screen->pitch; // get pixel at x,y-1 ir += p2[ridx]; ig += p2[gidx]; ib += p2[bidx]; ir/=4; ig/=4; ib/=4; p[ridx]=ir; p[gidx]=ig; p[bidx]=ib; p += screen->pitch; } } } void explode(SDL_Surface *screen, int samplex, int sampley, int samplew, int sampleh) { int ridx=screen->format->Rshift/8; int gidx=screen->format->Gshift/8; int bidx=screen->format->Bshift/8; int dist=(int)(10*(3.0f - delay)); int x,y; for (x=samplex; x < samplex + samplew; x ++ ) { uint8_t *p = (uint8_t *)screen->pixels + x * screen->format->BytesPerPixel + sampley * screen->pitch; for (y=sampley; y < sampley + sampleh; y ++ ) { int ir=0,ig=0,ib=0,i; for (i=0; i < 3; i++) { int dx = TCOD_random_get_int(NULL,-dist,dist); int dy = TCOD_random_get_int(NULL,-dist,dist); uint8_t *p2; p2 = p + dx * screen->format->BytesPerPixel; p2 += dy * screen->pitch; ir += p2[ridx]; ig += p2[gidx]; ib += p2[bidx]; } ir/=3; ig/=3; ib/=3; p[ridx]=ir; p[gidx]=ig; p[bidx]=ib; p += screen->pitch; } } } void blur(SDL_Surface *screen, int samplex, int sampley, int samplew, int sampleh) { // let's blur that sample console float f[3],n=0.0f; int ridx=screen->format->Rshift/8; int gidx=screen->format->Gshift/8; int bidx=screen->format->Bshift/8; int x,y; f[2]=TCOD_sys_elapsed_seconds(); if ( noise == NULL ) noise=TCOD_noise_new(3, TCOD_NOISE_DEFAULT_HURST, TCOD_NOISE_DEFAULT_LACUNARITY, NULL); for (x=samplex; x < samplex + samplew; x ++ ) { uint8_t *p = (uint8_t *)screen->pixels + x * screen->format->BytesPerPixel + sampley * screen->pitch; f[0]=(float)(x)/samplew; for (y=sampley; y < sampley + sampleh; y ++ ) { int ir=0,ig=0,ib=0,dec, count; if ( (y-sampley)%8 == 0 ) { f[1]=(float)(y)/sampleh; n=TCOD_noise_get_fbm(noise,f,3.0f); } dec = (int)(3*(n+1.0f)); count=0; switch(dec) { case 4: count += 4; // get pixel at x,y ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p -= 2*screen->format->BytesPerPixel; // get pixel at x+2,y ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p -= 2*screen->pitch; // get pixel at x+2,y+2 ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p+= 2*screen->format->BytesPerPixel; // get pixel at x,y+2 ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p += 2*screen->pitch; case 3: count += 4; // get pixel at x,y ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p += 2*screen->format->BytesPerPixel; // get pixel at x+2,y ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p += 2*screen->pitch; // get pixel at x+2,y+2 ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p-= 2*screen->format->BytesPerPixel; // get pixel at x,y+2 ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p -= 2*screen->pitch; case 2: count += 4; // get pixel at x,y ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p -= screen->format->BytesPerPixel; // get pixel at x-1,y ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p -= screen->pitch; // get pixel at x-1,y-1 ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p+= screen->format->BytesPerPixel; // get pixel at x,y-1 ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p += screen->pitch; case 1: count += 4; // get pixel at x,y ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p += screen->format->BytesPerPixel; // get pixel at x+1,y ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p += screen->pitch; // get pixel at x+1,y+1 ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p-= screen->format->BytesPerPixel; // get pixel at x,y+1 ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p -= screen->pitch; ir/=count; ig/=count; ib/=count; p[ridx]=ir; p[gidx]=ig; p[bidx]=ib; break; default:break; } p += screen->pitch; } } } void SDL_render(void *sdlSurface) { SDL_Surface *screen = (SDL_Surface *)sdlSurface; // now we have almighty access to the screen's precious pixels !! // get the font character size int charw,charh,samplex,sampley; TCOD_sys_get_char_size(&charw,&charh); // compute the sample console position in pixels samplex = SAMPLE_SCREEN_X * charw; sampley = SAMPLE_SCREEN_Y * charh; delay -= TCOD_sys_get_last_frame_length(); if ( delay < 0.0f ) { delay = 3.0f; effectNum = (effectNum + 1) % 3; if ( effectNum == 2 ) sdl_callback_enabled=false; // no forced redraw for burn effect else sdl_callback_enabled=true; } switch(effectNum) { case 0 : blur(screen,samplex,sampley,SAMPLE_SCREEN_WIDTH * charw,SAMPLE_SCREEN_HEIGHT * charh); break; case 1 : explode(screen,samplex,sampley,SAMPLE_SCREEN_WIDTH * charw,SAMPLE_SCREEN_HEIGHT * charh); break; case 2 : burn(screen,samplex,sampley,SAMPLE_SCREEN_WIDTH * charw,SAMPLE_SCREEN_HEIGHT * charh); break; } } void render_sdl(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse) { if ( first ) { TCOD_sys_set_fps(30); /* limited to 30 fps */ // use noise sample as background. rendering is done in SampleRenderer TCOD_console_set_default_background(sample_console,TCOD_light_blue); TCOD_console_set_default_foreground(sample_console,TCOD_white); TCOD_console_clear(sample_console); TCOD_console_print_rect_ex(sample_console,SAMPLE_SCREEN_WIDTH/2,3,SAMPLE_SCREEN_WIDTH,0, TCOD_BKGND_NONE, TCOD_CENTER, "The SDL callback gives you access to the screen surface so that you can alter the pixels one by one using SDL API or any API on top of SDL. SDL is used here to blur the sample console.\n\nHit TAB to enable/disable the callback. While enabled, it will be active on other samples too.\n\nNote that the SDL callback only works with SDL renderer."); } if ( key->vk == TCODK_TAB ) { sdl_callback_enabled = !sdl_callback_enabled; if (sdl_callback_enabled) { TCOD_sys_register_SDL_renderer(SDL_render); } else { TCOD_sys_register_SDL_renderer(NULL); // we want libtcod to redraw the sample console even if nothing has changed in it TCOD_console_set_dirty(SAMPLE_SCREEN_X,SAMPLE_SCREEN_Y,SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT); } } } #endif /* *************************** * the list of samples * ***************************/ sample_t samples[] = { {" True colors ",render_colors}, {" Offscreen console ",render_offscreen}, {" Line drawing ",render_lines}, {" Noise ",render_noise}, {" Field of view ",render_fov}, {" Path finding ",render_path}, {" Bsp toolkit ",render_bsp}, {" Image toolkit ",render_image}, {" Mouse support ",render_mouse}, {" Name generator ",render_name}, #ifndef NO_SDL_SAMPLE {" SDL callback ",render_sdl}, #endif }; int nb_samples = sizeof(samples)/sizeof(sample_t); /* total number of samples */ /* *************************** * the main function * ***************************/ #ifdef __ANDROID__ int SDL_main( int argc, char *argv[] ) { #else int main( int argc, char *argv[] ) { #endif int cur_sample=0; /* index of the current sample */ bool first=true; /* first time we render a sample */ int i; TCOD_key_t key = {TCODK_NONE,0}; TCOD_mouse_t mouse; char *font="data/fonts/consolas10x10_gs_tc.png"; int nb_char_horiz=0,nb_char_vertic=0; int argn; int fullscreen_width=0; int fullscreen_height=0; int font_flags=TCOD_FONT_TYPE_GREYSCALE|TCOD_FONT_LAYOUT_TCOD; int font_new_flags=0; TCOD_renderer_t renderer=TCOD_RENDERER_SDL; bool fullscreen=false; bool credits_end=false; int cur_renderer=0; static const char *renderer_name[TCOD_NB_RENDERERS] = { "F1 GLSL ","F2 OPENGL ","F3 SDL " }; /* initialize the root console (open the game window) */ for (argn=1; argn < argc; argn++) { if ( strcmp(argv[argn],"-font") == 0 && argn+1 < argc) { argn++; font=argv[argn]; font_flags=0; } else if ( strcmp(argv[argn],"-font-nb-char") == 0 && argn+2 < argc ) { argn++; nb_char_horiz=atoi(argv[argn]); argn++; nb_char_vertic=atoi(argv[argn]); font_flags=0; } else if ( strcmp(argv[argn],"-fullscreen-resolution") == 0 && argn+2 < argc ) { argn++; fullscreen_width=atoi(argv[argn]); argn++; fullscreen_height=atoi(argv[argn]); } else if ( strcmp(argv[argn],"-renderer") == 0 && argn+1 < argc ) { argn++; renderer=(TCOD_renderer_t)atoi(argv[argn]); } else if ( strcmp(argv[argn],"-fullscreen") == 0 ) { fullscreen=true; } else if ( strcmp(argv[argn],"-font-in-row") == 0 ) { font_flags=0; font_new_flags |= TCOD_FONT_LAYOUT_ASCII_INROW; } else if ( strcmp(argv[argn],"-font-greyscale") == 0 ) { font_flags=0; font_new_flags |= TCOD_FONT_TYPE_GREYSCALE; } else if ( strcmp(argv[argn],"-font-tcod") == 0 ) { font_flags=0; font_new_flags |= TCOD_FONT_LAYOUT_TCOD; } else if ( strcmp(argv[argn],"-help") == 0 || strcmp(argv[argn],"-?") == 0) { printf ("options :\n"); printf ("-font : use a custom font\n"); printf ("-font-nb-char : number of characters in the font\n"); printf ("-font-in-row : the font layout is in row instead of columns\n"); printf ("-font-tcod : the font uses TCOD layout instead of ASCII\n"); printf ("-font-greyscale : antialiased font using greyscale bitmap\n"); printf ("-fullscreen : start in fullscreen\n"); printf ("-fullscreen-resolution : force fullscreen resolution\n"); printf ("-renderer : set renderer. 0 : GLSL 1 : OPENGL 2 : SDL\n"); exit(0); } else { /* ignore parameter */ } } if ( font_flags == 0 ) font_flags=font_new_flags; TCOD_console_set_custom_font(font,font_flags,nb_char_horiz,nb_char_vertic); if ( fullscreen_width > 0 ) { TCOD_sys_force_fullscreen_resolution(fullscreen_width,fullscreen_height); } TCOD_console_init_root(80,50,"libtcod C sample",fullscreen, renderer); /* initialize the offscreen console for the samples */ sample_console = TCOD_console_new(SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT); do { if (! credits_end) { credits_end=TCOD_console_credits_render(60,43,false); } /* print the list of samples */ for (i=0; i < nb_samples; i++ ) { if ( i == cur_sample ) { /* set colors for currently selected sample */ TCOD_console_set_default_foreground(NULL,TCOD_white); TCOD_console_set_default_background(NULL,TCOD_light_blue); } else { /* set colors for other samples */ TCOD_console_set_default_foreground(NULL,TCOD_grey); TCOD_console_set_default_background(NULL,TCOD_black); } /* print the sample name */ TCOD_console_print_ex(NULL,2,46-(nb_samples-i),TCOD_BKGND_SET,TCOD_LEFT,samples[i].name); } /* print the help message */ TCOD_console_set_default_foreground(NULL,TCOD_grey); TCOD_console_print_ex(NULL,79,46,TCOD_BKGND_NONE,TCOD_RIGHT,"last frame : %3d ms (%3d fps)", (int)(TCOD_sys_get_last_frame_length()*1000), TCOD_sys_get_fps()); TCOD_console_print_ex(NULL,79,47,TCOD_BKGND_NONE,TCOD_RIGHT,"elapsed : %8dms %4.2fs", TCOD_sys_elapsed_milli(),TCOD_sys_elapsed_seconds()); TCOD_console_print(NULL,2,47,"%c%c : select a sample", TCOD_CHAR_ARROW_N,TCOD_CHAR_ARROW_S); TCOD_console_print(NULL,2,48,"ALT-ENTER : switch to %s", TCOD_console_is_fullscreen() ? "windowed mode " : "fullscreen mode"); /* render current sample */ samples[cur_sample].render(first,&key,&mouse); first=false; /* blit the sample console on the root console */ TCOD_console_blit(sample_console,0,0,SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT, /* the source console & zone to blit */ NULL,SAMPLE_SCREEN_X,SAMPLE_SCREEN_Y, /* the destination console & position */ 1.0f,1.0f /* alpha coefs */ ); #ifndef NO_SDL_SAMPLE if ( sdl_callback_enabled ) { // we want libtcod to redraw the sample console even if nothing has changed in it TCOD_console_set_dirty(SAMPLE_SCREEN_X,SAMPLE_SCREEN_Y,SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT); } #endif /* display renderer list and current renderer */ cur_renderer=TCOD_sys_get_renderer(); TCOD_console_set_default_foreground(NULL,TCOD_grey); TCOD_console_set_default_background(NULL,TCOD_black); TCOD_console_print_ex(NULL,42,46-(TCOD_NB_RENDERERS+1),TCOD_BKGND_SET,TCOD_LEFT,"Renderer :"); for (i=0; i < TCOD_NB_RENDERERS; i++) { if (i==cur_renderer) { /* set colors for current renderer */ TCOD_console_set_default_foreground(NULL,TCOD_white); TCOD_console_set_default_background(NULL,TCOD_light_blue); } else { /* set colors for other renderer */ TCOD_console_set_default_foreground(NULL,TCOD_grey); TCOD_console_set_default_background(NULL,TCOD_black); } TCOD_console_print_ex(NULL,42,46-(TCOD_NB_RENDERERS-i),TCOD_BKGND_SET,TCOD_LEFT,renderer_name[i]); } /* update the game screen */ TCOD_console_flush(); /* did the user hit a key ? */ TCOD_sys_check_for_event((TCOD_event_t)(TCOD_EVENT_KEY_PRESS|TCOD_EVENT_MOUSE),&key,&mouse); if ( key.vk == TCODK_DOWN ) { /* down arrow : next sample */ cur_sample = (cur_sample+1) % nb_samples; first=true; } else if ( key.vk == TCODK_UP ) { /* up arrow : previous sample */ cur_sample--; if ( cur_sample < 0 ) cur_sample = nb_samples-1; first=true; } else if ( key.vk == TCODK_ENTER && key.lalt ) { /* ALT-ENTER : switch fullscreen */ TCOD_console_set_fullscreen(!TCOD_console_is_fullscreen()); } else if ( key.vk == TCODK_PRINTSCREEN ) { if ( key.lalt ) { /* Alt-PrintScreen : save to samples.asc */ TCOD_console_save_asc(NULL,"samples.asc"); } else { /* save screenshot */ TCOD_sys_save_screenshot(NULL); } } else if (key.vk==TCODK_F1) { /* switch renderers with F1,F2,F3 */ TCOD_sys_set_renderer(TCOD_RENDERER_GLSL); } else if (key.vk==TCODK_F2) { TCOD_sys_set_renderer(TCOD_RENDERER_OPENGL); } else if (key.vk==TCODK_F3) { TCOD_sys_set_renderer(TCOD_RENDERER_SDL); } } while (!TCOD_console_is_window_closed()); return 0; } libtcod-1.6.4+dfsg/samples/samples_cpp.cpp000066400000000000000000001534201321276576200205570ustar00rootroot00000000000000/* * libtcod CPP samples * This code demonstrates various usages of libtcod modules * It's in the public domain. */ // uncomment this to disable SDL sample (might cause compilation issues on some systems) //#define NO_SDL_SAMPLE #include #include #include #include #include "libtcod.hpp" #define _SDL_main_h #include // a sample has a name and a rendering function typedef struct { char name[64]; void (*render)(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse); } sample_t; // sample screen size #define SAMPLE_SCREEN_WIDTH 46 #define SAMPLE_SCREEN_HEIGHT 20 // sample screen position #define SAMPLE_SCREEN_X 20 #define SAMPLE_SCREEN_Y 10 // *************************** // samples rendering functions // *************************** // the offscreen console in which the samples are rendered TCODConsole sampleConsole(SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT); // *************************** // true colors sample // *************************** void render_colors(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse) { enum { TOPLEFT, TOPRIGHT, BOTTOMLEFT, BOTTOMRIGHT }; static TCODColor cols[4]={TCODColor(50,40,150),TCODColor(240,85,5),TCODColor(50,35,240),TCODColor(10,200,130)}; // random corner colors static int dirr[4]={1,-1,1,1},dirg[4]={1,-1,-1,1},dirb[4]={1,1,1,-1}; if ( first ) { TCODSystem::setFps(0); // unlimited fps sampleConsole.clear(); } // ==== slighty modify the corner colors ==== for (int c=0; c < 4; c++) { // move each corner color int component=TCODRandom::getInstance()->getInt(0,2); switch (component) { case 0 : cols[c].r+=5*dirr[c]; if ( cols[c].r == 255 ) dirr[c]=-1; else if (cols[c].r==0) dirr[c]=1; break; case 1 : cols[c].g+=5*dirg[c]; if ( cols[c].g == 255 ) dirg[c]=-1; else if (cols[c].g==0) dirg[c]=1; break; case 2 : cols[c].b+=5*dirb[c]; if ( cols[c].b == 255 ) dirb[c]=-1; else if (cols[c].b==0) dirb[c]=1; break; } } // ==== scan the whole screen, interpolating corner colors ==== for (int x=0; x < SAMPLE_SCREEN_WIDTH; x++) { float xcoef = (float)(x)/(SAMPLE_SCREEN_WIDTH-1); // get the current column top and bottom colors TCODColor top = TCODColor::lerp(cols[TOPLEFT], cols[TOPRIGHT],xcoef); TCODColor bottom = TCODColor::lerp(cols[BOTTOMLEFT], cols[BOTTOMRIGHT],xcoef); for (int y=0; y < SAMPLE_SCREEN_HEIGHT; y++) { float ycoef = (float)(y)/(SAMPLE_SCREEN_HEIGHT-1); // get the current cell color TCODColor curColor = TCODColor::lerp(top,bottom,ycoef); sampleConsole.setCharBackground(x,y,curColor,TCOD_BKGND_SET); } } // ==== print the text with a random color ==== // get the background color at the text position TCODColor textColor=sampleConsole.getCharBackground(SAMPLE_SCREEN_WIDTH/2,5); // and invert it textColor.r=255-textColor.r; textColor.g=255-textColor.g; textColor.b=255-textColor.b; // put random text (for performance tests) for (int x=0; x < SAMPLE_SCREEN_WIDTH; x++) { for (int y=0; y < SAMPLE_SCREEN_HEIGHT; y++) { int c; TCODColor col=sampleConsole.getCharBackground(x,y); col=TCODColor::lerp(col,TCODColor::black,0.5f); // use colored character 255 on first and last lines if ( y == 0 || y == SAMPLE_SCREEN_HEIGHT-1) { c=255; } else { c=TCODRandom::getInstance()->getInt('a','z'); } sampleConsole.setDefaultForeground(col); sampleConsole.putChar(x,y,c,TCOD_BKGND_NONE); } } sampleConsole.setDefaultForeground(textColor); // the background behind the text is slightly darkened using the BKGND_MULTIPLY flag sampleConsole.setDefaultBackground(TCODColor::grey); sampleConsole.printRectEx(SAMPLE_SCREEN_WIDTH/2,5,SAMPLE_SCREEN_WIDTH-2,SAMPLE_SCREEN_HEIGHT-1, TCOD_BKGND_MULTIPLY,TCOD_CENTER, "The Doryen library uses 24 bits colors, for both background and foreground."); } // *************************** // offscreen console sample // *************************** void render_offscreen(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse) { static TCODConsole secondary(SAMPLE_SCREEN_WIDTH/2,SAMPLE_SCREEN_HEIGHT/2); // second screen static TCODConsole screenshot(SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT); // second screen static bool init=false; // draw the secondary screen only the first time static int counter=0; static int x=0,y=0; // secondary screen position static int xdir=1,ydir=1; // movement direction if (! init ) { init=true; secondary.printFrame(0,0,SAMPLE_SCREEN_WIDTH/2,SAMPLE_SCREEN_HEIGHT/2,false,TCOD_BKGND_SET,"Offscreen console"); secondary.printRectEx(SAMPLE_SCREEN_WIDTH/4,2,SAMPLE_SCREEN_WIDTH/2-2,SAMPLE_SCREEN_HEIGHT/2, TCOD_BKGND_NONE,TCOD_CENTER,"You can render to an offscreen console and blit in on another one, simulating alpha transparency."); } if ( first ) { TCODSystem::setFps(30); // fps limited to 30 // get a "screenshot" of the current sample screen TCODConsole::blit(&sampleConsole,0,0,SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT, &screenshot,0,0); } counter++; if ( counter % 20 == 0 ) { // move the secondary screen every 2 seconds x+=xdir;y+=ydir; if ( x == SAMPLE_SCREEN_WIDTH/2+5 ) xdir=-1; else if ( x == -5 ) xdir=1; if ( y == SAMPLE_SCREEN_HEIGHT/2+5 ) ydir=-1; else if ( y == -5 ) ydir=1; } // restore the initial screen TCODConsole::blit(&screenshot,0,0,SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT, &sampleConsole,0,0); // blit the overlapping screen TCODConsole::blit(&secondary,0,0,SAMPLE_SCREEN_WIDTH/2,SAMPLE_SCREEN_HEIGHT/2, &sampleConsole,x,y,1.0f,0.75f); } // *************************** // line drawing sample // *************************** static int bkFlag=TCOD_BKGND_SET; // current blending mode class LineListener : public TCODLineListener { public : bool putPoint(int x, int y) { if ( x>= 0 && y >= 0 && x < SAMPLE_SCREEN_WIDTH && y < SAMPLE_SCREEN_HEIGHT) { sampleConsole.setCharBackground(x,y,TCODColor::lightBlue,(TCOD_bkgnd_flag_t)bkFlag); } return true; } }; void render_lines(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse) { static TCODConsole bk(SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT); // colored background static bool init=false; static const char *flagNames[]={ "TCOD_BKGND_NONE", "TCOD_BKGND_SET", "TCOD_BKGND_MULTIPLY", "TCOD_BKGND_LIGHTEN", "TCOD_BKGND_DARKEN", "TCOD_BKGND_SCREEN", "TCOD_BKGND_COLOR_DODGE", "TCOD_BKGND_COLOR_BURN", "TCOD_BKGND_ADD", "TCOD_BKGND_ADDALPHA", "TCOD_BKGND_BURN", "TCOD_BKGND_OVERLAY", "TCOD_BKGND_ALPHA" }; if ( key->vk == TCODK_ENTER || key->vk == TCODK_KPENTER ) { // switch to the next blending mode bkFlag++; if ( (bkFlag &0xff) > TCOD_BKGND_ALPH) bkFlag=TCOD_BKGND_NONE; } if ( (bkFlag & 0xff) == TCOD_BKGND_ALPH) { // for the alpha mode, update alpha every frame float alpha = (1.0f+cosf(TCODSystem::getElapsedSeconds()*2))/2.0f; bkFlag=TCOD_BKGND_ALPHA(alpha); } else if ( (bkFlag & 0xff) == TCOD_BKGND_ADDA) { // for the add alpha mode, update alpha every frame float alpha = (1.0f+cosf(TCODSystem::getElapsedSeconds()*2))/2.0f; bkFlag=TCOD_BKGND_ADDALPHA(alpha); } if (!init) { // initialize the colored background for (int x=0; x < SAMPLE_SCREEN_WIDTH; x ++) { for (int y=0; y < SAMPLE_SCREEN_HEIGHT; y++) { TCODColor col; col.r = (uint8_t)(x* 255 / (SAMPLE_SCREEN_WIDTH-1)); col.g = (uint8_t)((x+y)* 255 / (SAMPLE_SCREEN_WIDTH-1+SAMPLE_SCREEN_HEIGHT-1)); col.b = (uint8_t)(y* 255 / (SAMPLE_SCREEN_HEIGHT-1)); bk.setCharBackground(x,y,col, TCOD_BKGND_SET); } } init=true; } if ( first ) { TCODSystem::setFps(30); // fps limited to 30 sampleConsole.setDefaultForeground(TCODColor::white); } // blit the background TCODConsole::blit(&bk,0,0,SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT,&sampleConsole,0,0); // render the gradient int recty=(int)((SAMPLE_SCREEN_HEIGHT-2)*((1.0f+cosf(TCODSystem::getElapsedSeconds()))/2.0f)); for (int x=0;x < SAMPLE_SCREEN_WIDTH; x++) { TCODColor col; col.r=(uint8_t)(x*255/SAMPLE_SCREEN_WIDTH); col.g=(uint8_t)(x*255/SAMPLE_SCREEN_WIDTH); col.b=(uint8_t)(x*255/SAMPLE_SCREEN_WIDTH); sampleConsole.setCharBackground(x,recty,col,(TCOD_bkgnd_flag_t)bkFlag); sampleConsole.setCharBackground(x,recty+1,col,(TCOD_bkgnd_flag_t)bkFlag); sampleConsole.setCharBackground(x,recty+2,col,(TCOD_bkgnd_flag_t)bkFlag); } // calculate the segment ends float angle = TCODSystem::getElapsedSeconds()*2.0f; float cosAngle=cosf(angle); float sinAngle=sinf(angle); int xo = (int)(SAMPLE_SCREEN_WIDTH/2*(1 + cosAngle)); int yo = (int)(SAMPLE_SCREEN_HEIGHT/2 + sinAngle * SAMPLE_SCREEN_WIDTH/2); int xd = (int)(SAMPLE_SCREEN_WIDTH/2*(1 - cosAngle)); int yd = (int)(SAMPLE_SCREEN_HEIGHT/2 - sinAngle * SAMPLE_SCREEN_WIDTH/2); // render the line LineListener listener; TCODLine::line(xo,yo,xd,yd,&listener); // print the current flag sampleConsole.print(2,2,"%s (ENTER to change)",flagNames[bkFlag&0xff]); } // *************************** // noise sample // *************************** void render_noise(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse) { enum { PERLIN,SIMPLEX,WAVELET, FBM_PERLIN,TURBULENCE_PERLIN, FBM_SIMPLEX,TURBULENCE_SIMPLEX, FBM_WAVELET,TURBULENCE_WAVELET }; // which function we render static const char *funcName[]={ "1 : perlin noise ", "2 : simplex noise ", "3 : wavelet noise ", "4 : perlin fbm ", "5 : perlin turbulence ", "6 : simplex fbm ", "7 : simplex turbulence ", "8 : wavelet fbm ", "9 : wavelet turbulence ", }; static int func=PERLIN; static TCODNoise *noise=NULL; static float dx=0.0f, dy=0.0f; static float octaves=4.0f; static float hurst=TCOD_NOISE_DEFAULT_HURST; static float lacunarity=TCOD_NOISE_DEFAULT_LACUNARITY; static TCODImage *img=NULL; static float zoom=3.0f; if ( !noise) { noise = new TCODNoise(2,hurst,lacunarity); img = new TCODImage(SAMPLE_SCREEN_WIDTH*2,SAMPLE_SCREEN_HEIGHT*2); } if ( first ) { TCODSystem::setFps(30); // fps limited to 30 } // texture animation dx+=0.01f; dy+=0.01f; // render the 2d noise function for (int y=0; y < 2*SAMPLE_SCREEN_HEIGHT; y++ ) { for (int x=0; x < 2*SAMPLE_SCREEN_WIDTH; x++ ) { float f[2]; f[0] = zoom*x / (2*SAMPLE_SCREEN_WIDTH) + dx; f[1] = zoom*y / (2*SAMPLE_SCREEN_HEIGHT) + dy; float value = 0.0f; switch (func ) { case PERLIN : value = noise->get(f,TCOD_NOISE_PERLIN); break; case SIMPLEX : value = noise->get(f,TCOD_NOISE_SIMPLEX); break; case WAVELET : value = noise->get(f,TCOD_NOISE_WAVELET); break; case FBM_PERLIN : value = noise->getFbm(f,octaves,TCOD_NOISE_PERLIN); break; case TURBULENCE_PERLIN : value = noise->getTurbulence(f,octaves,TCOD_NOISE_PERLIN); break; case FBM_SIMPLEX : value = noise->getFbm(f,octaves,TCOD_NOISE_SIMPLEX); break; case TURBULENCE_SIMPLEX : value = noise->getTurbulence(f,octaves,TCOD_NOISE_SIMPLEX); break; case FBM_WAVELET : value = noise->getFbm(f,octaves,TCOD_NOISE_WAVELET); break; case TURBULENCE_WAVELET : value = noise->getTurbulence(f,octaves,TCOD_NOISE_WAVELET); break; } uint8_t c=(uint8_t)((value+1.0f)/2.0f*255); // use a bluish color TCODColor col((uint8_t)(c/2),(uint8_t)(c/2),c); img->putPixel(x,y,col); } } // blit the noise image on the console with subcell resolution img->blit2x(&sampleConsole,0,0); // draw a transparent rectangle sampleConsole.setDefaultBackground(TCODColor::grey); sampleConsole.rect(2,2,23,(func <= WAVELET ? 10 : 13),false,TCOD_BKGND_MULTIPLY); for (int y=2; y < 2+(func <= WAVELET ? 10 : 13); y++ ) { for (int x=2; x < 2+23; x++ ) { TCODColor col=sampleConsole.getCharForeground(x,y); col = col * TCODColor::grey; sampleConsole.setCharForeground(x,y,col); } } // draw the text for (int curfunc=PERLIN; curfunc <= TURBULENCE_WAVELET; curfunc++) { if ( curfunc == func ) { sampleConsole.setDefaultForeground(TCODColor::white); sampleConsole.setDefaultBackground(TCODColor::lightBlue); sampleConsole.printEx(2,2+curfunc,TCOD_BKGND_SET,TCOD_LEFT,funcName[curfunc]); } else { sampleConsole.setDefaultForeground(TCODColor::grey); sampleConsole.print(2,2+curfunc,funcName[curfunc]); } } // draw parameters sampleConsole.setDefaultForeground(TCODColor::white); sampleConsole.print(2,11,"Y/H : zoom (%2.1f)",zoom); if ( func > WAVELET ) { sampleConsole.print(2,12,"E/D : hurst (%2.1f)",hurst); sampleConsole.print(2,13,"R/F : lacunarity (%2.1f)",lacunarity); sampleConsole.print(2,14,"T/G : octaves (%2.1f)",octaves); } // handle keypress if ( key->vk == TCODK_NONE) return; if ( key->c >= '1' && key->c <= '9') { // change the noise function func = key->c - '1'; } else if ( key->c == 'E' || key->c == 'e' ) { // increase hurst hurst+=0.1f; delete noise; noise = new TCODNoise(2,hurst,lacunarity); } else if ( key->c == 'D' || key->c == 'd' ) { // decrease hurst hurst-=0.1f; delete noise; noise = new TCODNoise(2,hurst,lacunarity); } else if ( key->c == 'R' || key->c == 'r' ) { // increase lacunarity lacunarity+=0.5f; delete noise; noise = new TCODNoise(2,hurst,lacunarity); } else if ( key->c == 'F' || key->c == 'f' ) { // decrease lacunarity lacunarity-=0.5f; delete noise; noise = new TCODNoise(2,hurst,lacunarity); } else if ( key->c == 'T' || key->c == 't' ) { // increase octaves octaves+=0.5f; } else if ( key->c == 'G' || key->c == 'g' ) { // decrease octaves octaves-=0.5f; } else if ( key->c == 'Y' || key->c == 'y' ) { // increase zoom zoom+=0.2f; } else if ( key->c == 'H' || key->c == 'h' ) { // decrease zoom zoom-=0.2f; } } // *************************** // fov sample // *************************** void render_fov(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse) { static const char *smap[] = { "##############################################", "####################### #################", "##################### # ###############", "###################### ### ###########", "################## ##### ####", "################ ######## ###### ####", "############### #################### ####", "################ ###### ##", "######## ####### ###### # # # ##", "######## ###### ### ##", "######## ##", "#### ###### ### # # # ##", "#### ### ########## #### ##", "#### ### ########## ###########=##########", "#### ################## ##### #####", "#### ### #### ##### #####", "#### # #### #####", "######## # #### ##### #####", "######## ##### ####################", "##############################################", }; #define TORCH_RADIUS 10.0f #define SQUARED_TORCH_RADIUS (TORCH_RADIUS*TORCH_RADIUS) static int px=20,py=10; // player position static bool recomputeFov=true; // the player moved. must recompute fov static bool torch=false; // torch fx on ? static TCODMap *map=NULL; static TCODColor darkWall(0,0,100); static TCODColor lightWall(130,110,50); static TCODColor darkGround(50,50,150); static TCODColor lightGround(200,180,50); static TCODNoise *noise=NULL; static bool light_walls=true; static int algonum=0; static const char *algo_names[]={"BASIC ", "DIAMOND ", "SHADOW ", "PERMISSIVE0","PERMISSIVE1","PERMISSIVE2","PERMISSIVE3","PERMISSIVE4", "PERMISSIVE5","PERMISSIVE6","PERMISSIVE7","PERMISSIVE8","RESTRICTIVE"}; static float torchx=0.0f; // torch light position in the perlin noise if ( ! map) { // initialize the map for the fov toolkit map = new TCODMap(SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT); for (int y=0; y < SAMPLE_SCREEN_HEIGHT; y++ ) { for (int x=0; x < SAMPLE_SCREEN_WIDTH; x++ ) { if ( smap[y][x] == ' ' ) map->setProperties(x,y,true,true);// ground else if ( smap[y][x] == '=' ) map->setProperties(x,y,true,false); // window } } // 1d noise used for the torch flickering noise=new TCODNoise(1); } if ( first ) { TCODSystem::setFps(30); // fps limited to 30 // we draw the foreground only the first time. // during the player movement, only the @ is redrawn. // the rest impacts only the background color // draw the help text & player @ sampleConsole.clear(); sampleConsole.setDefaultForeground(TCODColor::white); sampleConsole.print(1,0,"IJKL : move around\nT : torch fx %s\nW : light walls %s\n+-: algo %s", torch ? "on " : "off", light_walls ? "on " : "off", algo_names[algonum]); sampleConsole.setDefaultForeground(TCODColor::black); sampleConsole.putChar(px,py,'@',TCOD_BKGND_NONE); // draw windows for (int y=0; y < SAMPLE_SCREEN_HEIGHT; y++ ) { for (int x=0; x < SAMPLE_SCREEN_WIDTH; x++ ) { if ( smap[y][x] == '=' ) { sampleConsole.putChar(x,y,TCOD_CHAR_DHLINE,TCOD_BKGND_NONE); } } } } if ( recomputeFov ) { // calculate the field of view from the player position recomputeFov=false; map->computeFov(px,py,torch ? (int)(TORCH_RADIUS) : 0,light_walls,(TCOD_fov_algorithm_t)algonum); } // torch position & intensity variation float dx=0.0f,dy=0.0f,di=0.0f; if ( torch ) { // slightly change the perlin noise parameter torchx+=0.2f; // randomize the light position between -1.5 and 1.5 float tdx=torchx+20.0f; dx = noise->get(&tdx)*1.5f; tdx += 30.0f; dy = noise->get(&tdx)*1.5f; // randomize the light intensity between -0.2 and 0.2 di = 0.2f * noise->get(&torchx); } // draw the dungeon for (int y=0; y < SAMPLE_SCREEN_HEIGHT; y++ ) { for (int x=0; x < SAMPLE_SCREEN_WIDTH; x++ ) { bool visible = map->isInFov(x,y); bool wall=smap[y][x]=='#'; if (! visible ) { sampleConsole.setCharBackground(x,y,wall ? darkWall:darkGround,TCOD_BKGND_SET); } else { TCODColor light; if ( !torch ) { light = wall ? lightWall : lightGround; } else { // torch flickering fx TCODColor base=(wall ? darkWall : darkGround); light=(wall ? lightWall : lightGround); // cell distance to torch (squared) float r=(float)((x-px+dx)*(x-px+dx)+(y-py+dy)*(y-py+dy)); if ( r < SQUARED_TORCH_RADIUS ) { // l = 1.0 at player position, 0.0 at a radius of 10 cells float l = (SQUARED_TORCH_RADIUS-r)/SQUARED_TORCH_RADIUS +di; l=CLAMP(0.0f,1.0f,l); // interpolate the color base = TCODColor::lerp(base,light,l); } light=base; } sampleConsole.setCharBackground(x,y,light, TCOD_BKGND_SET ); } } } if ( key->c == 'I' || key->c == 'i' ) { // player move north if ( smap[py-1][px] == ' ' ) { sampleConsole.putChar(px,py,' ',TCOD_BKGND_NONE); py--; sampleConsole.putChar(px,py,'@',TCOD_BKGND_NONE); recomputeFov=true; } } else if ( key->c == 'K' || key->c == 'k' ) { // player move south if ( smap[py+1][px] == ' ' ) { sampleConsole.putChar(px,py,' ',TCOD_BKGND_NONE); py++; sampleConsole.putChar(px,py,'@',TCOD_BKGND_NONE); recomputeFov=true; } } else if ( key->c == 'J' || key->c == 'j' ) { // player move west if ( smap[py][px-1] == ' ' ) { sampleConsole.putChar(px,py,' ',TCOD_BKGND_NONE); px--; sampleConsole.putChar(px,py,'@',TCOD_BKGND_NONE); recomputeFov=true; } } else if ( key->c == 'L' || key->c == 'l' ) { // player move east if ( smap[py][px+1] == ' ' ) { sampleConsole.putChar(px,py,' ',TCOD_BKGND_NONE); px++; sampleConsole.putChar(px,py,'@',TCOD_BKGND_NONE); recomputeFov=true; } } else if ( key->c == 'T' || key->c == 't' ) { // enable/disable the torch fx torch=!torch; sampleConsole.setDefaultForeground(TCODColor::white); sampleConsole.print(1,0,"IJKL : move around\nT : torch fx %s\nW : light walls %s\n+-: algo %s", torch ? "on " : "off", light_walls ? "on " : "off", algo_names[algonum]); sampleConsole.setDefaultForeground(TCODColor::black); } else if ( key->c == 'W' || key->c == 'w' ) { light_walls=!light_walls; sampleConsole.setDefaultForeground(TCODColor::white); sampleConsole.print(1,0,"IJKL : move around\nT : torch fx %s\nW : light walls %s\n+-: algo %s", torch ? "on " : "off", light_walls ? "on " : "off", algo_names[algonum]); sampleConsole.setDefaultForeground(TCODColor::black); recomputeFov=true; } else if ( key->c == '+' || key->c == '-' ) { algonum+= key->c == '+' ? 1 : -1; algonum=CLAMP(0,NB_FOV_ALGORITHMS-1,algonum); sampleConsole.setDefaultForeground(TCODColor::white); sampleConsole.print(1,0,"IJKL : move around\nT : torch fx %s\nW : light walls %s\n+-: algo %s", torch ? "on " : "off", light_walls ? "on " : "off", algo_names[algonum]); sampleConsole.setDefaultForeground(TCODColor::black); recomputeFov=true; } } // *************************** // image sample // *************************** void render_image(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse) { static TCODImage * img=NULL, *circle = NULL; static TCODColor blue(0,0,255); static TCODColor green(0,255,0); if ( img == NULL ) { img=new TCODImage("data/img/skull.png"); img->setKeyColor(TCODColor::black); circle=new TCODImage("data/img/circle.png"); } if ( first ) { TCODSystem::setFps(30); // fps limited to 30 } sampleConsole.setDefaultBackground(TCODColor::black); sampleConsole.clear(); float x=SAMPLE_SCREEN_WIDTH/2+cosf(TCODSystem::getElapsedSeconds())*10.0f; float y=(float)(SAMPLE_SCREEN_HEIGHT/2); float scalex=0.2f+1.8f*(1.0f+cosf(TCODSystem::getElapsedSeconds()/2))/2.0f; float scaley=scalex; float angle=TCODSystem::getElapsedSeconds(); long elapsed=TCODSystem::getElapsedMilli()/2000; if ( elapsed & 1 ) { // split the color channels of circle.png // the red channel sampleConsole.setDefaultBackground(TCODColor::red); sampleConsole.rect(0,3,15,15,false,TCOD_BKGND_SET); circle->blitRect(&sampleConsole,0,3,-1,-1,TCOD_BKGND_MULTIPLY); // the green channel sampleConsole.setDefaultBackground(green); sampleConsole.rect(15,3,15,15,false,TCOD_BKGND_SET); circle->blitRect(&sampleConsole,15,3,-1,-1,TCOD_BKGND_MULTIPLY); // the blue channel sampleConsole.setDefaultBackground(blue); sampleConsole.rect(30,3,15,15,false,TCOD_BKGND_SET); circle->blitRect(&sampleConsole,30,3,-1,-1,TCOD_BKGND_MULTIPLY); } else { // render circle.png with normal blitting circle->blitRect(&sampleConsole,0,3,-1,-1,TCOD_BKGND_SET); circle->blitRect(&sampleConsole,15,3,-1,-1,TCOD_BKGND_SET); circle->blitRect(&sampleConsole,30,3,-1,-1,TCOD_BKGND_SET); } img->blit(&sampleConsole,x,y, TCOD_BKGND_SET,scalex,scaley,angle); } // *************************** // mouse sample // ***************************/ void render_mouse(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse) { static bool lbut=false,rbut=false,mbut=false; if ( first ) { TCODSystem::setFps(30); // fps limited to 30 sampleConsole.setDefaultBackground(TCODColor::grey); sampleConsole.setDefaultForeground(TCODColor::lightYellow); TCODMouse::move(320,200); TCODMouse::showCursor(true); } sampleConsole.clear(); if ( mouse->lbutton_pressed ) lbut=!lbut; if ( mouse->rbutton_pressed ) rbut=!rbut; if ( mouse->mbutton_pressed ) mbut=!mbut; sampleConsole.print(1,1, "%s\n" "Mouse position : %4dx%4d %s\n" "Mouse cell : %4dx%4d\n" "Mouse movement : %4dx%4d\n" "Left button : %s (toggle %s)\n" "Right button : %s (toggle %s)\n" "Middle button : %s (toggle %s)\n" "Wheel : %s\n", TCODConsole::isActive() ? "" : "APPLICATION INACTIVE", mouse->x,mouse->y,TCODConsole::hasMouseFocus() ? "" : "OUT OF FOCUS", mouse->cx,mouse->cy, mouse->dx,mouse->dy, mouse->lbutton ? " ON" : "OFF",lbut ? " ON" : "OFF", mouse->rbutton ? " ON" : "OFF",rbut ? " ON" : "OFF", mouse->mbutton ? " ON" : "OFF",mbut ? " ON" : "OFF", mouse->wheel_up ? "UP" : (mouse->wheel_down ? "DOWN" : "") ); sampleConsole.print(1,10,"1 : Hide cursor\n2 : Show cursor"); if (key->c == '1') TCODMouse::showCursor(false); else if( key->c == '2' ) TCODMouse::showCursor(true); } // *************************** // path sample // *************************** void render_path(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse) { static const char *smap[] = { "##############################################", "####################### #################", "##################### # ###############", "###################### ### ###########", "################## ##### ####", "################ ######## ###### ####", "############### #################### ####", "################ ###### ##", "######## ####### ###### # # # ##", "######## ###### ### ##", "######## ##", "#### ###### ### # # # ##", "#### ### ########## #### ##", "#### ### ########## ###########=##########", "#### ################## ##### #####", "#### ### #### ##### #####", "#### # #### #####", "######## # #### ##### #####", "######## ##### ####################", "##############################################", }; #define TORCH_RADIUS 10.0f #define SQUARED_TORCH_RADIUS (TORCH_RADIUS*TORCH_RADIUS) static int px=20,py=10; // player position static int dx=24,dy=1; // destination static TCODMap *map=NULL; static TCODColor darkWall(0,0,100); static TCODColor darkGround(50,50,150); static TCODColor lightGround(200,180,50); static TCODPath *path=NULL; static bool usingAstar=true; static float dijkstraDist=0; static TCODDijkstra *dijkstra = NULL; static bool recalculatePath=false; static float busy; static int oldChar=' '; int mx,my; if ( ! map) { // initialize the map for the fov toolkit map = new TCODMap(SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT); for (int y=0; y < SAMPLE_SCREEN_HEIGHT; y++ ) { for (int x=0; x < SAMPLE_SCREEN_WIDTH; x++ ) { if ( smap[y][x] == ' ' ) map->setProperties(x,y,true,true);// ground else if ( smap[y][x] == '=' ) map->setProperties(x,y,true,false); // window } } path=new TCODPath(map); dijkstra = new TCODDijkstra(map); } if ( first ) { TCODSystem::setFps(30); // fps limited to 30 // we draw the foreground only the first time. // during the player movement, only the @ is redrawn. // the rest impacts only the background color // draw the help text & player @ sampleConsole.clear(); sampleConsole.setDefaultForeground(TCODColor::white); sampleConsole.putChar(dx,dy,'+',TCOD_BKGND_NONE); sampleConsole.putChar(px,py,'@',TCOD_BKGND_NONE); sampleConsole.print(1,1,"IJKL / mouse :\nmove destination\nTAB : A*/dijkstra"); sampleConsole.print(1,4,"Using : A*"); // draw windows for (int y=0; y < SAMPLE_SCREEN_HEIGHT; y++ ) { for (int x=0; x < SAMPLE_SCREEN_WIDTH; x++ ) { if ( smap[y][x] == '=' ) { sampleConsole.putChar(x,y,TCOD_CHAR_DHLINE,TCOD_BKGND_NONE); } } } recalculatePath=true; } if ( recalculatePath ) { if (usingAstar) { path->compute(px,py,dx,dy); } else { dijkstraDist=0.0f; // compute the distance grid dijkstra->compute(px,py); // get the maximum distance (needed for ground shading only) for (int y=0; y < SAMPLE_SCREEN_HEIGHT; y++ ) { for (int x=0; x < SAMPLE_SCREEN_WIDTH; x++ ) { float d= dijkstra->getDistance(x,y); if ( d > dijkstraDist ) dijkstraDist=d; } } // compute the path dijkstra->setPath(dx,dy); } recalculatePath=false; busy=0.2f; } // draw the dungeon for (int y=0; y < SAMPLE_SCREEN_HEIGHT; y++ ) { for (int x=0; x < SAMPLE_SCREEN_WIDTH; x++ ) { bool wall=smap[y][x]=='#'; sampleConsole.setCharBackground(x,y,wall ? darkWall : darkGround, TCOD_BKGND_SET ); } } // draw the path if ( usingAstar ) { for (int i=0; i< path->size(); i++ ) { int x,y; path->get(i,&x,&y); sampleConsole.setCharBackground(x,y,lightGround, TCOD_BKGND_SET ); } } else { for (int y=0; y < SAMPLE_SCREEN_HEIGHT; y++ ) { for (int x=0; x < SAMPLE_SCREEN_WIDTH; x++ ) { bool wall=smap[y][x]=='#'; if (! wall) { float d= dijkstra->getDistance(x,y); sampleConsole.setCharBackground(x,y,TCODColor::lerp(lightGround,darkGround,0.9f * d / dijkstraDist), TCOD_BKGND_SET ); } } } for (int i=0; i< dijkstra->size(); i++ ) { int x,y; dijkstra->get(i,&x,&y); sampleConsole.setCharBackground(x,y,lightGround, TCOD_BKGND_SET ); } } // move the creature busy-=TCODSystem::getLastFrameLength(); if (busy <= 0.0f ) { busy = 0.2f; if ( usingAstar ) { if (!path->isEmpty()) { sampleConsole.putChar(px,py,' ',TCOD_BKGND_NONE); path->walk(&px,&py,true); sampleConsole.putChar(px,py,'@',TCOD_BKGND_NONE); } } else { if (!dijkstra->isEmpty()) { sampleConsole.putChar(px,py,' ',TCOD_BKGND_NONE); dijkstra->walk(&px,&py); sampleConsole.putChar(px,py,'@',TCOD_BKGND_NONE); recalculatePath=true; } } } if ( (key->c == 'I' || key->c == 'i') && dy > 0 ) { // destination move north sampleConsole.putChar(dx,dy,oldChar,TCOD_BKGND_NONE); dy--; oldChar=sampleConsole.getChar(dx,dy); sampleConsole.putChar(dx,dy,'+',TCOD_BKGND_NONE); if ( smap[dy][dx] == ' ' ) { recalculatePath=true; } } else if (( key->c == 'K' || key->c == 'k' ) && dy < SAMPLE_SCREEN_HEIGHT-1 ) { // destination move south sampleConsole.putChar(dx,dy,oldChar,TCOD_BKGND_NONE); dy++; oldChar=sampleConsole.getChar(dx,dy); sampleConsole.putChar(dx,dy,'+',TCOD_BKGND_NONE); if ( smap[dy][dx] == ' ' ) { recalculatePath=true; } } else if (( key->c == 'J' || key->c == 'j' ) && dx > 0 ) { // destination move west sampleConsole.putChar(dx,dy,oldChar,TCOD_BKGND_NONE); dx--; oldChar=sampleConsole.getChar(dx,dy); sampleConsole.putChar(dx,dy,'+',TCOD_BKGND_NONE); if ( smap[dy][dx] == ' ' ) { recalculatePath=true; } } else if (( key->c == 'L' || key->c == 'l' ) && dx < SAMPLE_SCREEN_WIDTH -1 ) { // destination move east sampleConsole.putChar(dx,dy,oldChar,TCOD_BKGND_NONE); dx++; oldChar=sampleConsole.getChar(dx,dy); sampleConsole.putChar(dx,dy,'+',TCOD_BKGND_NONE); if ( smap[dy][dx] == ' ' ) { recalculatePath=true; } } else if ( key->vk == TCODK_TAB ) { usingAstar = ! usingAstar; if ( usingAstar ) sampleConsole.print(1,4,"Using : A* "); else sampleConsole.print(1,4,"Using : Dijkstra"); recalculatePath=true; } mx = mouse->cx-SAMPLE_SCREEN_X; my = mouse->cy-SAMPLE_SCREEN_Y; if ( mx >= 0 && mx < SAMPLE_SCREEN_WIDTH && my >= 0 && my < SAMPLE_SCREEN_HEIGHT && ( dx != mx || dy != my ) ) { sampleConsole.putChar(dx,dy,oldChar,TCOD_BKGND_NONE); dx=mx;dy=my; oldChar=sampleConsole.getChar(dx,dy); sampleConsole.putChar(dx,dy,'+',TCOD_BKGND_NONE); if ( smap[dy][dx] == ' ' ) { recalculatePath=true; } } } // *************************** // bsp sample // *************************** static int bspDepth=8; static int minRoomSize=4; static bool randomRoom=false; // a room fills a random part of the node or the maximum available space ? static bool roomWalls=true; // if true, there is always a wall on north & west side of a room typedef char map_t[SAMPLE_SCREEN_WIDTH][SAMPLE_SCREEN_HEIGHT]; // draw a vertical line void vline(map_t *map,int x, int y1, int y2) { int y=y1; int dy=(y1>y2?-1:1); (*map)[x][y]=' '; if ( y1 == y2 ) return; do { y+=dy; (*map)[x][y]=' '; } while (y!=y2); } // draw a vertical line up until we reach an empty space void vline_up(map_t *map,int x, int y) { while (y >= 0 && (*map)[x][y] != ' ') { (*map)[x][y]=' '; y--; } } // draw a vertical line down until we reach an empty space void vline_down(map_t *map,int x, int y) { while (y < SAMPLE_SCREEN_HEIGHT && (*map)[x][y] != ' ') { (*map)[x][y]=' '; y++; } } // draw a horizontal line void hline(map_t *map,int x1, int y, int x2) { int x=x1; int dx=(x1>x2?-1:1); (*map)[x][y]=' '; if ( x1 == x2 ) return; do { x+=dx; (*map)[x][y]=' '; } while (x!=x2); } // draw a horizontal line left until we reach an empty space void hline_left(map_t *map,int x, int y) { while (x >= 0 && (*map)[x][y] != ' ') { (*map)[x][y]=' '; x--; } } // draw a horizontal line right until we reach an empty space void hline_right(map_t *map,int x, int y) { while (x < SAMPLE_SCREEN_WIDTH && (*map)[x][y] != ' ') { (*map)[x][y]=' '; x++; } } // the class building the dungeon from the bsp nodes //#include class BspListener : public ITCODBspCallback { public : bool visitNode(TCODBsp *node, void *userData) { map_t *map=(map_t *)userData; if ( node->isLeaf() ) { // calculate the room size int minx = node->x+1; int maxx = node->x+node->w-1; int miny = node->y+1; int maxy = node->y+node->h-1; if (! roomWalls ) { if ( minx > 1 ) minx--; if ( miny > 1 ) miny--; } if (maxx == SAMPLE_SCREEN_WIDTH-1 ) maxx--; if (maxy == SAMPLE_SCREEN_HEIGHT-1 ) maxy--; if ( randomRoom ) { minx = TCODRandom::getInstance()->getInt(minx,maxx-minRoomSize+1); miny = TCODRandom::getInstance()->getInt(miny,maxy-minRoomSize+1); maxx = TCODRandom::getInstance()->getInt(minx+minRoomSize-1,maxx); maxy = TCODRandom::getInstance()->getInt(miny+minRoomSize-1,maxy); } // resize the node to fit the room //printf("node %dx%d %dx%d => room %dx%d %dx%d\n",node->x,node->y,node->w,node->h,minx,miny,maxx-minx+1,maxy-miny+1); node->x=minx; node->y=miny; node->w=maxx-minx+1; node->h=maxy-miny+1; // dig the room for (int x=minx; x <= maxx; x++ ) { for (int y=miny; y <= maxy; y++ ) { (*map)[x][y]=' '; } } } else { //printf("lvl %d %dx%d %dx%d\n",node->level, node->x,node->y,node->w,node->h); // resize the node to fit its sons TCODBsp *left=node->getLeft(); TCODBsp *right=node->getRight(); node->x=MIN(left->x,right->x); node->y=MIN(left->y,right->y); node->w=MAX(left->x+left->w,right->x+right->w)-node->x; node->h=MAX(left->y+left->h,right->y+right->h)-node->y; // create a corridor between the two lower nodes if (node->horizontal) { // vertical corridor if ( left->x+left->w -1 < right->x || right->x+right->w-1 < left->x ) { // no overlapping zone. we need a Z shaped corridor int x1=TCODRandom::getInstance()->getInt(left->x,left->x+left->w-1); int x2=TCODRandom::getInstance()->getInt(right->x,right->x+right->w-1); int y=TCODRandom::getInstance()->getInt(left->y+left->h,right->y); vline_up(map,x1,y-1); hline(map,x1,y,x2); vline_down(map,x2,y+1); } else { // straight vertical corridor int minx=MAX(left->x,right->x); int maxx=MIN(left->x+left->w-1,right->x+right->w-1); int x=TCODRandom::getInstance()->getInt(minx,maxx); vline_down(map,x,right->y); vline_up(map,x,right->y-1); } } else { // horizontal corridor if ( left->y+left->h -1 < right->y || right->y+right->h-1 < left->y ) { // no overlapping zone. we need a Z shaped corridor int y1=TCODRandom::getInstance()->getInt(left->y,left->y+left->h-1); int y2=TCODRandom::getInstance()->getInt(right->y,right->y+right->h-1); int x=TCODRandom::getInstance()->getInt(left->x+left->w,right->x); hline_left(map,x-1,y1); vline(map,x,y1,y2); hline_right(map,x+1,y2); } else { // straight horizontal corridor int miny=MAX(left->y,right->y); int maxy=MIN(left->y+left->h-1,right->y+right->h-1); int y=TCODRandom::getInstance()->getInt(miny,maxy); hline_left(map,right->x-1,y); hline_right(map,right->x,y); } } } return true; } }; void render_bsp(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse) { static TCODBsp *bsp=NULL; static bool generate=true; static bool refresh=false; static map_t map; static TCODColor darkWall(0,0,100); static TCODColor darkGround(50,50,150); static BspListener listener; if ( generate || refresh ) { // dungeon generation if (! bsp ) { // create the bsp bsp = new TCODBsp(0,0,SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT); } else { // restore the nodes size bsp->resize(0,0,SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT); } memset(map,'#',sizeof(char)*SAMPLE_SCREEN_WIDTH*SAMPLE_SCREEN_HEIGHT); if ( generate ) { // build a new random bsp tree bsp->removeSons(); bsp->splitRecursive(NULL,bspDepth,minRoomSize+(roomWalls?1:0),minRoomSize+(roomWalls?1:0),1.5f,1.5f); } // create the dungeon from the bsp bsp->traverseInvertedLevelOrder(&listener,&map); generate=false; refresh=false; } sampleConsole.clear(); sampleConsole.setDefaultForeground(TCODColor::white); sampleConsole.print(1,1,"ENTER : rebuild bsp\nSPACE : rebuild dungeon\n+-: bsp depth %d\n*/: room size %d\n1 : random room size %s", bspDepth,minRoomSize, randomRoom ? "ON" : "OFF"); if ( randomRoom ) sampleConsole.print(1,6,"2 : room walls %s", roomWalls ? "ON" : "OFF" ); // render the level for (int y=0; y < SAMPLE_SCREEN_HEIGHT; y++ ) { for (int x=0; x < SAMPLE_SCREEN_WIDTH; x++ ) { bool wall= ( map[x][y] == '#' ); sampleConsole.setCharBackground(x,y,wall ? darkWall : darkGround, TCOD_BKGND_SET ); } } if ( key->vk == TCODK_ENTER || key->vk == TCODK_KPENTER ) { generate=true; } else if (key->c==' ') { refresh=true; } else if (key->c=='+') { bspDepth++; generate=true; } else if (key->c=='-' && bspDepth > 1) { bspDepth--; generate=true; } else if (key->c=='*') { minRoomSize++; generate=true; } else if (key->c=='/' && minRoomSize > 2) { minRoomSize--; generate=true; } else if (key->c=='1' || key->vk == TCODK_1 || key->vk == TCODK_KP1) { randomRoom=!randomRoom; if (! randomRoom ) roomWalls=true; refresh=true; } else if (key->c=='2' || key->vk == TCODK_2 || key->vk == TCODK_KP2) { roomWalls=!roomWalls; refresh=true; } } /* *************************** * name generator sample * ***************************/ void render_name(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse) { static int nbSets=0; static int curSet=0; static float delay=0.0f; static TCODList names; static TCODList sets; int i; if ( nbSets == 0 ) { TCODList files=TCODSystem::getDirectoryContent("data/namegen","*.cfg"); // parse all the files for (char **it=files.begin(); it != files.end(); it++) { char tmp[256]; sprintf(tmp, "data/namegen/%s",*it); TCODNamegen::parse(tmp); } // get the sets list sets = TCODNamegen::getSets(); nbSets = sets.size(); } if ( first ) { TCODSystem::setFps(30); /* limited to 30 fps */ } while ( names.size() >= 15 ) { // remove the first element. #ifndef TCOD_VISUAL_STUDIO char *nameToRemove= * (names.begin()); #endif names.remove(names.begin()); // for some reason, this crashes on MSVC... #ifndef TCOD_VISUAL_STUDIO free(nameToRemove); #endif } sampleConsole.setDefaultBackground(TCODColor::lightBlue); sampleConsole.clear(); sampleConsole.setDefaultForeground(TCODColor::white); sampleConsole.print(1,1,"%s\n\n+ : next generator\n- : prev generator", sets.get(curSet)); for (i=0; i < names.size(); i++) { char *name=names.get(i); if ( strlen(name)< SAMPLE_SCREEN_WIDTH ) sampleConsole.printEx(SAMPLE_SCREEN_WIDTH-2,2+i,TCOD_BKGND_NONE,TCOD_RIGHT,name); } delay += TCODSystem::getLastFrameLength(); if ( delay >= 0.5f ) { delay -= 0.5f; // add a new name to the list names.push(TCODNamegen::generate(sets.get(curSet),true)); } if ( key->c == '+' ) { curSet ++; if ( curSet == nbSets ) curSet=0; names.push(strdup("======")); } else if ( key->c == '-' ) { curSet --; if ( curSet < 0 ) curSet=nbSets-1; names.push(strdup("======")); } } /* *************************** * SDL callback sample * ***************************/ #ifndef NO_SDL_SAMPLE static bool sdl_callback_enabled=false; class SampleRenderer : public ITCODSDLRenderer { public : SampleRenderer() : effectNum(0), delay(3.0f) { noise=new TCODNoise(3); } ~SampleRenderer() { delete noise; } void render(void *sdlSurface) { SDL_Surface *screen = (SDL_Surface *)sdlSurface; // now we have almighty access to the screen's precious pixels !! // get the font character size int charw,charh; TCODSystem::getCharSize(&charw,&charh); // compute the sample console position in pixels int samplex = SAMPLE_SCREEN_X * charw; int sampley = SAMPLE_SCREEN_Y * charh; delay -= TCODSystem::getLastFrameLength(); if ( delay < 0.0f ) { delay = 3.0f; effectNum = (effectNum + 1) % 3; if ( effectNum == 2 ) sdl_callback_enabled=false; // no forced redraw for burn effect else sdl_callback_enabled=true; } switch(effectNum) { case 0 : blur(screen,samplex,sampley,SAMPLE_SCREEN_WIDTH * charw,SAMPLE_SCREEN_HEIGHT * charh); break; case 1 : explode(screen,samplex,sampley,SAMPLE_SCREEN_WIDTH * charw,SAMPLE_SCREEN_HEIGHT * charh); break; case 2 : burn(screen,samplex,sampley,SAMPLE_SCREEN_WIDTH * charw,SAMPLE_SCREEN_HEIGHT * charh); break; } } protected : TCODNoise *noise; int effectNum; float delay; void burn(SDL_Surface *screen, int samplex, int sampley, int samplew, int sampleh) { int ridx=screen->format->Rshift/8; int gidx=screen->format->Gshift/8; int bidx=screen->format->Bshift/8; for (int x=samplex; x < samplex + samplew; x ++ ) { uint8_t *p = (uint8_t *)screen->pixels + x * screen->format->BytesPerPixel + sampley * screen->pitch; for (int y=sampley; y < sampley + sampleh; y ++ ) { int ir=0,ig=0,ib=0; uint8_t *p2 = p + screen->format->BytesPerPixel; // get pixel at x+1,y ir += p2[ridx]; ig += p2[gidx]; ib += p2[bidx]; p2 -= 2*screen->format->BytesPerPixel; // get pixel at x-1,y ir += p2[ridx]; ig += p2[gidx]; ib += p2[bidx]; p2 += screen->format->BytesPerPixel+ screen->pitch; // get pixel at x,y+1 ir += p2[ridx]; ig += p2[gidx]; ib += p2[bidx]; p2 -= 2*screen->pitch; // get pixel at x,y-1 ir += p2[ridx]; ig += p2[gidx]; ib += p2[bidx]; ir/=4; ig/=4; ib/=4; p[ridx]=ir; p[gidx]=ig; p[bidx]=ib; p += screen->pitch; } } } void explode(SDL_Surface *screen, int samplex, int sampley, int samplew, int sampleh) { int ridx=screen->format->Rshift/8; int gidx=screen->format->Gshift/8; int bidx=screen->format->Bshift/8; TCODRandom *rng=TCODRandom::getInstance(); int dist=(int)(10*(3.0f - delay)); for (int x=samplex; x < samplex + samplew; x ++ ) { uint8_t *p = (uint8_t *)screen->pixels + x * screen->format->BytesPerPixel + sampley * screen->pitch; for (int y=sampley; y < sampley + sampleh; y ++ ) { int ir=0,ig=0,ib=0; for (int i=0; i < 3; i++) { int dx = rng->getInt(-dist,dist); int dy = rng->getInt(-dist,dist); uint8_t *p2; p2 = p + dx * screen->format->BytesPerPixel; p2 += dy * screen->pitch; ir += p2[ridx]; ig += p2[gidx]; ib += p2[bidx]; } ir/=3; ig/=3; ib/=3; p[ridx]=ir; p[gidx]=ig; p[bidx]=ib; p += screen->pitch; } } } void blur(SDL_Surface *screen, int samplex, int sampley, int samplew, int sampleh) { // let's blur that sample console float f[3],n=0.0f; int ridx=screen->format->Rshift/8; int gidx=screen->format->Gshift/8; int bidx=screen->format->Bshift/8; f[2]=TCODSystem::getElapsedSeconds(); for (int x=samplex; x < samplex + samplew; x ++ ) { uint8_t *p = (uint8_t *)screen->pixels + x * screen->format->BytesPerPixel + sampley * screen->pitch; f[0]=(float)(x)/samplew; for (int y=sampley; y < sampley + sampleh; y ++ ) { int ir=0,ig=0,ib=0; if ( (y-sampley)%8 == 0 ) { f[1]=(float)(y)/sampleh; n=noise->getFbm(f,3.0f); } int dec = (int)(3*(n+1.0f)); int count=0; switch(dec) { case 4: count += 4; // get pixel at x,y ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p -= 2*screen->format->BytesPerPixel; // get pixel at x+2,y ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p -= 2*screen->pitch; // get pixel at x+2,y+2 ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p+= 2*screen->format->BytesPerPixel; // get pixel at x,y+2 ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p += 2*screen->pitch; case 3: count += 4; // get pixel at x,y ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p += 2*screen->format->BytesPerPixel; // get pixel at x+2,y ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p += 2*screen->pitch; // get pixel at x+2,y+2 ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p-= 2*screen->format->BytesPerPixel; // get pixel at x,y+2 ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p -= 2*screen->pitch; case 2: count += 4; // get pixel at x,y ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p -= screen->format->BytesPerPixel; // get pixel at x-1,y ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p -= screen->pitch; // get pixel at x-1,y-1 ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p+= screen->format->BytesPerPixel; // get pixel at x,y-1 ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p += screen->pitch; case 1: count += 4; // get pixel at x,y ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p += screen->format->BytesPerPixel; // get pixel at x+1,y ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p += screen->pitch; // get pixel at x+1,y+1 ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p-= screen->format->BytesPerPixel; // get pixel at x,y+1 ir += p[ridx]; ig += p[gidx]; ib += p[bidx]; p -= screen->pitch; ir/=count; ig/=count; ib/=count; p[ridx]=ir; p[gidx]=ig; p[bidx]=ib; break; default:break; } p += screen->pitch; } } } }; void render_sdl(bool first, TCOD_key_t*key, TCOD_mouse_t *mouse) { if ( first ) { TCODSystem::setFps(30); /* limited to 30 fps */ // use noise sample as background. rendering is done in SampleRenderer sampleConsole.setDefaultBackground(TCODColor::lightBlue); sampleConsole.setDefaultForeground(TCODColor::white); sampleConsole.clear(); sampleConsole.printRectEx(SAMPLE_SCREEN_WIDTH/2,3,SAMPLE_SCREEN_WIDTH,0, TCOD_BKGND_NONE,TCOD_CENTER, "The SDL callback gives you access to the screen surface so that you can alter the pixels one by one using SDL API or any API on top of SDL. SDL is used here to blur the sample console.\n\nHit TAB to enable/disable the callback. While enabled, it will be active on other samples too.\n\nNote that the SDL callback only works with SDL renderer."); } if ( key->vk == TCODK_TAB ) { sdl_callback_enabled = !sdl_callback_enabled; if (sdl_callback_enabled) { TCODSystem::registerSDLRenderer(new SampleRenderer()); } else { TCODSystem::registerSDLRenderer(NULL); // we want libtcod to redraw the sample console even if nothing has changed in it TCODConsole::root->setDirty(SAMPLE_SCREEN_X,SAMPLE_SCREEN_Y,SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT); } } } #endif // *************************** // the list of samples // *************************** sample_t samples[] = { {" True colors ",render_colors}, {" Offscreen console ",render_offscreen}, {" Line drawing ",render_lines}, {" Noise ",render_noise}, {" Field of view ",render_fov}, {" Path finding ",render_path}, {" Bsp toolkit ",render_bsp}, {" Image toolkit ",render_image}, {" Mouse support ",render_mouse}, {" Name generator ",render_name}, #ifndef NO_SDL_SAMPLE {" SDL callback ",render_sdl}, #endif }; int nbSamples = sizeof(samples)/sizeof(sample_t); // total number of samples // *************************** // the main function // *************************** int main( int argc, char *argv[] ) { int curSample=0; // index of the current sample bool first=true; // first time we render a sample TCOD_key_t key = {TCODK_NONE,0}; TCOD_mouse_t mouse; const char *font="data/fonts/consolas10x10_gs_tc.png"; int nbCharHoriz=0,nbCharVertic=0; int argn; int fullscreenWidth=0; int fullscreenHeight=0; TCOD_renderer_t renderer=TCOD_RENDERER_SDL; bool fullscreen=false; int fontFlags=TCOD_FONT_TYPE_GREYSCALE|TCOD_FONT_LAYOUT_TCOD, fontNewFlags=0; bool creditsEnd=false; int cur_renderer=0; static const char *renderer_name[TCOD_NB_RENDERERS] = { "F1 GLSL ","F2 OPENGL ","F3 SDL " }; // initialize the root console (open the game window) for (argn=1; argn < argc; argn++) { if ( strcmp(argv[argn],"-font") == 0 && argn+1 < argc) { argn++; font=argv[argn]; fontFlags=0; } else if ( strcmp(argv[argn],"-font-nb-char") == 0 && argn+2 < argc ) { argn++; nbCharHoriz=atoi(argv[argn]); argn++; nbCharVertic=atoi(argv[argn]); fontFlags=0; } else if ( strcmp(argv[argn],"-fullscreen-resolution") == 0 && argn+2 < argc ) { argn++; fullscreenWidth=atoi(argv[argn]); argn++; fullscreenHeight=atoi(argv[argn]); } else if ( strcmp(argv[argn],"-renderer") == 0 && argn+1 < argc ) { argn++; renderer=(TCOD_renderer_t)atoi(argv[argn]); } else if ( strcmp(argv[argn],"-fullscreen") == 0 ) { fullscreen=true; } else if ( strcmp(argv[argn],"-font-in-row") == 0 ) { fontNewFlags |= TCOD_FONT_LAYOUT_ASCII_INROW; fontFlags=0; } else if ( strcmp(argv[argn],"-font-greyscale") == 0 ) { fontNewFlags |= TCOD_FONT_TYPE_GREYSCALE; fontFlags=0; } else if ( strcmp(argv[argn],"-font-tcod") == 0 ) { fontNewFlags |= TCOD_FONT_LAYOUT_TCOD; fontFlags=0; } else if ( strcmp(argv[argn],"-help") == 0 || strcmp(argv[argn],"-?") == 0) { printf ("options :\n"); printf ("-font : use a custom font\n"); printf ("-font-nb-char : number of characters in the font\n"); printf ("-font-in-row : the font layout is in row instead of columns\n"); printf ("-font-tcod : the font uses TCOD layout instead of ASCII\n"); printf ("-font-greyscale : antialiased font using greyscale bitmap\n"); printf ("-fullscreen : start in fullscreen\n"); printf ("-fullscreen-resolution : force fullscreen resolution\n"); printf ("-renderer : set renderer. 0 : GLSL 1 : OPENGL 2 : SDL\n"); exit(0); } else { // ignore parameter } } if ( fontFlags == 0 ) fontFlags=fontNewFlags; TCODConsole::setCustomFont(font,fontFlags,nbCharHoriz,nbCharVertic); if ( fullscreenWidth > 0 ) { TCODSystem::forceFullscreenResolution(fullscreenWidth,fullscreenHeight); } TCODConsole::initRoot(80,50,"libtcod C++ sample",fullscreen,renderer); do { if (! creditsEnd) { creditsEnd=TCODConsole::renderCredits(60,43,false); } // print the list of samples for (int i=0; i < nbSamples; i++ ) { if ( i == curSample ) { // set colors for currently selected sample TCODConsole::root->setDefaultForeground(TCODColor::white); TCODConsole::root->setDefaultBackground(TCODColor::lightBlue); } else { // set colors for other samples TCODConsole::root->setDefaultForeground(TCODColor::grey); TCODConsole::root->setDefaultBackground(TCODColor::black); } // print the sample name TCODConsole::root->printEx(2,46-(nbSamples-i),TCOD_BKGND_SET,TCOD_LEFT,samples[i].name); } // print the help message TCODConsole::root->setDefaultForeground(TCODColor::grey); TCODConsole::root->printEx(79,46,TCOD_BKGND_NONE,TCOD_RIGHT,"last frame : %3d ms (%3d fps)", (int)(TCODSystem::getLastFrameLength()*1000), TCODSystem::getFps()); TCODConsole::root->printEx(79,47,TCOD_BKGND_NONE,TCOD_RIGHT,"elapsed : %8dms %4.2fs", TCODSystem::getElapsedMilli(),TCODSystem::getElapsedSeconds()); TCODConsole::root->print(2,47,"%c%c : select a sample", TCOD_CHAR_ARROW_N, TCOD_CHAR_ARROW_S); TCODConsole::root->print(2,48,"ALT-ENTER : switch to %s", TCODConsole::isFullscreen() ? "windowed mode " : "fullscreen mode"); // render current sample samples[curSample].render(first,&key,&mouse); first=false; // blit the sample console on the root console TCODConsole::blit(&sampleConsole,0,0,SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT, // the source console & zone to blit TCODConsole::root,SAMPLE_SCREEN_X,SAMPLE_SCREEN_Y // the destination console & position ); // erase the renderer in debug mode (needed because the root console is not cleared each frame) TCODConsole::root->print(1,1," "); #ifndef NO_SDL_SAMPLE if ( sdl_callback_enabled ) { // we want libtcod to redraw the sample console even if nothing has changed in it TCODConsole::root->setDirty(SAMPLE_SCREEN_X,SAMPLE_SCREEN_Y,SAMPLE_SCREEN_WIDTH,SAMPLE_SCREEN_HEIGHT); } #endif /* display renderer list and current renderer */ cur_renderer=TCODSystem::getRenderer(); TCODConsole::root->setDefaultForeground(TCODColor::grey); TCODConsole::root->setDefaultBackground(TCODColor::black); TCODConsole::root->printEx(42,46-(TCOD_NB_RENDERERS+1),TCOD_BKGND_SET,TCOD_LEFT,"Renderer :"); for (int i=0; i < TCOD_NB_RENDERERS; i++) { if (i==cur_renderer) { /* set colors for current renderer */ TCODConsole::root->setDefaultForeground(TCODColor::white); TCODConsole::root->setDefaultBackground(TCODColor::lightBlue); } else { /* set colors for other renderer */ TCODConsole::root->setDefaultForeground(TCODColor::grey); TCODConsole::root->setDefaultBackground(TCODColor::black); } TCODConsole::root->printEx(42,46-(TCOD_NB_RENDERERS-i),TCOD_BKGND_SET,TCOD_LEFT,renderer_name[i]); } // update the game screen TCODConsole::flush(); // did the user hit a key ? TCODSystem::checkForEvent((TCOD_event_t)(TCOD_EVENT_KEY_PRESS|TCOD_EVENT_MOUSE),&key,&mouse); if ( key.vk == TCODK_DOWN ) { // down arrow : next sample curSample = (curSample+1) % nbSamples; first=true; } else if ( key.vk == TCODK_UP ) { // up arrow : previous sample curSample--; if ( curSample < 0 ) curSample = nbSamples-1; first=true; } else if ( key.vk == TCODK_ENTER && key.lalt ) { // ALT-ENTER : switch fullscreen TCODConsole::setFullscreen(!TCODConsole::isFullscreen()); #ifdef TCOD_LINUX } else if ( key.c == 'p' ) { #else } else if ( key.vk == TCODK_PRINTSCREEN ) { #endif if ( key.lalt ) { // ALT-PrintScreen : save to .asc format TCODConsole::root->saveApf("samples.apf"); } else { // save screenshot TCODSystem::saveScreenshot(NULL); } } else if (key.vk==TCODK_F1) { // switch renderers with F1,F2,F3 TCODSystem::setRenderer(TCOD_RENDERER_GLSL); } else if (key.vk==TCODK_F2) { TCODSystem::setRenderer(TCOD_RENDERER_OPENGL); } else if (key.vk==TCODK_F3) { TCODSystem::setRenderer(TCOD_RENDERER_SDL); } } while (!TCODConsole::isWindowClosed()); return 0; } libtcod-1.6.4+dfsg/samples/weather/000077500000000000000000000000001321276576200171775ustar00rootroot00000000000000libtcod-1.6.4+dfsg/samples/weather/main.cpp000066400000000000000000000145401321276576200206330ustar00rootroot00000000000000/* * Copyright (c) 2010 Jice * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "main.hpp" TCODNoise noise1d(1); TCODNoise noise2d(2); Weather weather; float dayTime=6*3600.0f; // starts at 6.00am TCODColor lightningColor(220,220,255); TCODImage *ground; void update(float elapsed, TCOD_key_t k, TCOD_mouse_t mouse) { if (k.c=='+') { float d=weather.getIndicatorDelta(); weather.setIndicatorDelta(d+elapsed*0.1f); } else if (k.c=='-') { float d=weather.getIndicatorDelta(); weather.setIndicatorDelta(d-elapsed*0.1f); } else if (k.vk == TCODK_ENTER || k.vk == TCODK_KPENTER) { elapsed*=20.0f; } dayTime += elapsed*60*3; // 1 real sec = 3 min if ( dayTime >= 24*3600 ) dayTime -= 24*3600; weather.update(elapsed); weather.calculateAmbient(dayTime); } const char *getDaytime() { static char buf[6]; int h=(int)(dayTime/3600); int m=(int)((dayTime-h*3600)/60); sprintf(buf,"%02d:%02d",h,m); return buf; } void render() { static TCODImage img(CON_W*2,CON_H*2); for (int x=0; x < CON_W*2; x++) { for (int y=0; y < CON_H*2; y++) { // we don't use color operation to avoid 0-255 clamping at every step // sort of poor man's HDR... int r=0,g=0,b=0; // default ground color TCODColor groundCol=ground->getPixel(x,y); // take cloud shadow into account float cloudCoef = weather.getCloud(x,y); r += (int)(cloudCoef * weather.getAmbientLightColor().r); g += (int)(cloudCoef * weather.getAmbientLightColor().g); b += (int)(cloudCoef * weather.getAmbientLightColor().b); // take lightning into account int lr=0,lg=0,lb=0; float lightning=weather.getLightning(x,y); if ( lightning > 0.0f ) { lr=(int)(2*lightning*lightningColor.r); lg=(int)(2*lightning*lightningColor.g); lb=(int)(2*lightning*lightningColor.b); r+=lr; g+=lg; b+=lb; } r=MIN(255,r); g=MIN(255,g); b=MIN(255,b); r=groundCol.r*r/200; g=groundCol.g*g/200; b=groundCol.b*b/200; img.putPixel(x,y,TCODColor(r,g,b)); } } img.blit2x(TCODConsole::root,0,0); // rain drops for (int x=0; x < CON_W; x++) { for (int y=0; y < CON_H; y++) { if ( weather.hasRainDrop() ) { float lightning=weather.getLightning(x*2,y*2); float cloudCoef = weather.getCloud(x*2,y*2); TCODColor col=TCODColor::darkBlue*cloudCoef; col = col * weather.getAmbientLightColor(); if ( lightning > 0.0f ) col = col + 2*lightning*lightningColor; TCODConsole::root->setChar(x,y,'/'); TCODConsole::root->setCharForeground(x,y,col); } } } TCODConsole::root->setDefaultForeground(TCODColor::white); TCODConsole::root->print(5,CON_H-12,"TCOD's weather system :\n" "- wind with varying speed and direction\n" "- rain\n" "- lightnings\n" "- day/night cycle\n" "Day time : %s\n" "Weather : %s\n\n" "Weather evolves automatically\nbut you can alter it by holding + or - : %.1f\n" "Accelerate time with ENTER",getDaytime(), weather.getWeather(), weather.getIndicatorDelta()); } int main (int argc, char *argv[]) { // initialize the game window TCODConsole::initRoot(CON_W,CON_H,"Weather system v" VERSION, false,TCOD_RENDERER_SDL); TCODMouse::showCursor(true); TCODSystem::setFps(25); weather.init(CON_W*2,CON_H*2); ground = new TCODImage(CON_W*2,CON_H*2); // generate some good locking ground TCODColor colors[] = { TCODColor(40,117,0), // grass TCODColor(69,125,0), // sparse grass TCODColor(110,125,0), // withered grass TCODColor(150,143,92), // dried grass TCODColor(133,115,71), // bare ground TCODColor(111,100,73) // dirt }; int keys[] = { 0,51,102,153,204,255 }; TCODColor gradientMap[256]; TCODColor::genMap(gradientMap,6,colors,keys); for (int x=0; x < CON_W*2; x++) { for (int y=0; y < CON_H*2; y++) { float f[2]={x*3.0f/CON_W,y*3.0f/CON_H}; float h=noise2d.getFbm(f,6.0f,TCOD_NOISE_SIMPLEX); int ih=(int)(h*256); ih=CLAMP(0,255,ih); float coef=1.0f; // darken the lower part (text background) if ( y > CON_H*2-27) coef=0.5f; TCODColor col=coef*gradientMap[ih]; // add some noise col = col * TCODRandom::getInstance()->getFloat(0.95f,1.05f); ground->putPixel(x,y,col); } } // for this demo, we want the weather to evolve quite rapidely weather.setChangeFactor(3.0f); bool endCredits=false; while (! TCODConsole::isWindowClosed()) { // read keyboard TCOD_key_t k=TCODConsole::checkForKeypress(TCOD_KEY_PRESSED|TCOD_KEY_RELEASED); TCOD_mouse_t mouse=TCODMouse::getStatus(); if ( k.vk == TCODK_PRINTSCREEN ) { // screenshot if (! k.pressed ) TCODSystem::saveScreenshot(NULL); k.vk=TCODK_NONE; } else if ( k.lalt && (k.vk == TCODK_ENTER || k.vk == TCODK_KPENTER) ) { // switch fullscreen if (! k.pressed ) TCODConsole::setFullscreen(!TCODConsole::isFullscreen()); k.vk=TCODK_NONE; } // update the game update(TCODSystem::getLastFrameLength(),k,mouse); // render the game screen render(); // render libtcod credits if (! endCredits ) endCredits = TCODConsole::renderCredits(4,4,true); // flush updates to screen TCODConsole::root->flush(); } return 0; } libtcod-1.6.4+dfsg/samples/weather/main.hpp000066400000000000000000000035031321276576200206350ustar00rootroot00000000000000/* * Copyright (c) 2010 Jice * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libtcod.hpp" #include "util_weather.hpp" #define VERSION "0.1.0" // console size #define CON_W 80 #define CON_H 50 #define IN_RECTANGLE(x,y,w,h) ((unsigned)(x) < (unsigned)(w) && (unsigned)(y) < (unsigned)(h)) #define SQRDIST(x1,y1,x2,y2) (((x1)-(x2))*((x1)-(x2))+((y1)-(y2))*((y1)-(y2))) #ifndef NDEBUG #define DBG(x) printf x #else #define DBG(x) #endif extern TCODNoise noise1d; extern TCODNoise noise2d; libtcod-1.6.4+dfsg/samples/weather/util_weather.cpp000066400000000000000000000173741321276576200224130ustar00rootroot00000000000000/* * Copyright (c) 2010 Jice * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "main.hpp" #define OCTAVES 7.0f #define SCALE 2.0f #define MAX_WIND_SPEED 4.0f #define LIGHTNING_LEVEL 0.4f #define LIGHTNING_RADIUS 500 #define LIGHTNING_LIFE 2.0f #define LIGHTNING_INTENSITY_SPEED 20.0f #define LIGHTNING_MIN_PROB 7.0f #define LIGHTNING_MAX_PROB 1.0f #define RAIN_MIN_PROB 4000 #define RAIN_MED_PROB 400 #define RAIN_MAX_PROB 10 void Weather::init(int width, int height) { map = new TCODHeightMap(width+2,height+2); // TODO : would be better with a 3d noise and slowly varying z // but you can notice the difference only when time is accelerated map->addFbm(&noise2d,SCALE,SCALE,0.0f,0.0f,OCTAVES,0.5f,0.5f); dx=dy=noisex=noisey=20000.0f; indicatorDelta=0.0f; changeFactor=1.0f; update(0.1f); } void Weather::move(int dx, int dy) { this->dx+=dx; this->dy+=dy; } const char *Weather::getWeather() { if (indicator > 0.9f ) return "The sky is completely clear."; else if ( indicator > 0.7f ) return "The sky is clear."; else if ( indicator > 0.6f ) return "It's cloudy."; else if ( indicator > 0.5f ) return "You feel a breeze."; else if ( indicator > 0.4f ) return "It's drizzling."; else if ( indicator > 0.3f ) return "It's raining."; else if ( indicator > 0.2f ) return "You get caught in a storm."; else return "The storm is raging"; } void Weather::update(float elapsed) { static float localElapsed=0.0f; localElapsed+=elapsed; float perlinx=changeFactor*localElapsed / 100.0f; indicator=(1.0f+noise1d.get(&perlinx, TCOD_NOISE_SIMPLEX))*0.5f + indicatorDelta; indicator=CLAMP(0.0f,1.0f,indicator); float windspeed=1.0f-indicator; perlinx*=2.0f; float windDir = (2.0f*3.1415926f*0.5f)*(1.0f+noise1d.get(&perlinx, TCOD_NOISE_SIMPLEX)); dx += MAX_WIND_SPEED * windspeed * cosf(windDir)*elapsed; dy += 0.5f * MAX_WIND_SPEED * windspeed * sinf(windDir) *elapsed; if ( indicator < LIGHTNING_LEVEL ) { float storm=(LIGHTNING_LEVEL-indicator)/LIGHTNING_LEVEL; // storm power 0-1 float lp = LIGHTNING_MIN_PROB + (int)((LIGHTNING_MAX_PROB-LIGHTNING_MIN_PROB) *storm); // nb of lightning per second int fps=TCODSystem::getFps(); if( fps > 0 ) { int ilp=(int)(lp * fps); if (TCODRandom::getInstance()->getInt(0,ilp)==0) { // new lightning lightning_t l; l.posx = TCODRandom::getInstance()->getInt(0,map->w); l.posy = TCODRandom::getInstance()->getInt(0,map->h); l.life = TCODRandom::getInstance()->getFloat(0.1f,LIGHTNING_LIFE); l.radius=TCODRandom::getInstance()->getInt(LIGHTNING_RADIUS,LIGHTNING_RADIUS*2); l.noisex=TCODRandom::getInstance()->getFloat(0.0f,1000.0f); l.intensity=0.0f; lightnings.push(l); } } } int bx=0,by=0; while ( dx >= 1.0f ) { dx-= 1.0f; noisex+=1.0f; bx++; } while ( dx <= -1.0f ) { dx+= 1.0f; noisex-=1.0f; bx--; } while ( dy >= 1.0f ) { dy-= 1.0f; noisey+=1.0f; by++; } while ( dy <= -1.0f ) { dy+= 1.0f; noisey-=1.0f; by--; } // update lightnings for (lightning_t *l=lightnings.begin(); l!= lightnings.end(); l++) { l->life-= elapsed; l->noisex+=elapsed*LIGHTNING_INTENSITY_SPEED; if (l->life<= 0) { l=lightnings.remove(l); } else { l->intensity=0.5f*noise1d.get(&l->noisex, TCOD_NOISE_SIMPLEX)+1.0f; l->posx-=bx; l->posy-=by; } } if ( bx || by ) { // recompute the whole map // TODO : should recompute only missing rows/columns // the world generator demo has that, but only for // horizontal move. Here clouds move in any direction map->clear(); map->addFbm(&noise2d,SCALE,SCALE,noisex,noisey,OCTAVES,0.5f,0.5f); } } float Weather::getCloud(int x, int y) { // cloud layer // 1.0 : no cloud // 0 : dark cloud. This way you can easily render ground with color * cloud coef float cdx=dx,cdy=dy; if ( dx >= 0 ) x++; else cdx=dx+1.0f; if ( dy >= 0 ) y++; else cdy=dy+1.0f; float val = map->getInterpolatedValue(x+cdx,y+cdy); // between 0 and 1 val += 2*indicator-0.5f; val = CLAMP(0.2f,1.0f,val); return val; } float Weather::getLightning(int x, int y) { if (indicator >= 0.3f) return 0.0f; if ( dx >= 0 ) x++; if ( dy >= 0 ) y++; float res=0.0f; float cloud=map->getValue(x,y); cloud = 1.0f - cloud; // inverted cloud. 0 = sky, 1=dark cloud cloud -= 0.6f; // no lightning under 0.6f. cloud is now 0 - 0.4 if ( cloud <= 0.0f ) return 0.0f; cloud = cloud / 0.4f; // now back to 0-1 range (but only for really cloudy zones) for (lightning_t *l=lightnings.begin(); l!= lightnings.end(); l++) { int dx=l->posx-x; int dy=l->posy-y; int dist=dx*dx+dy*dy; if ( dist < l->radius) { res+= l->intensity * (float)(l->radius-dist)/l->radius; } } float ret= cloud * res; return CLAMP(0.0f,1.0f,ret); } bool Weather::hasRainDrop() { if ( indicator >= 0.5f ) return false; int prob; if ( indicator >= 0.3f ) { prob = (int)(RAIN_MIN_PROB+(RAIN_MED_PROB-RAIN_MIN_PROB)*(0.5f-indicator)*5); } else { prob = (int)(RAIN_MED_PROB+(RAIN_MAX_PROB-RAIN_MED_PROB)*(0.3f-indicator)*3.33f); } int rp=TCODRandom::getInstance()->getInt(0,prob); return rp==0; } void Weather::calculateAmbient(float timeInSeconds) { // calculate ambient light static TCODColor night(0,0,128); static TCODColor dawn(196,0,0); static TCODColor dawn2(220,200,64); static TCODColor day(255,255,195); float coef=0.0f; float hour = timeInSeconds / 3600.0f; // TODO : should use a color gradient map for that.. if ( hour > 21.0f || hour < 6.0f ) { ambientColor=night; // night coef=0.0; } else if ( hour < 7.0f ) { // between 6am and 7am coef = (hour - 6.0f); ambientColor = TCODColor::lerp(night,dawn,coef); coef /= 3.0f; } else if ( hour < 8.0f ) { // between 7am and 8am coef = (hour - 7.0f); ambientColor = TCODColor::lerp(dawn,dawn2,coef); coef = 0.33333f + coef/3.0f; } else if ( hour < 9.0f ) { // between 8am and 9am coef = (hour - 8.0f); ambientColor = TCODColor::lerp(dawn2,day,coef); coef = 0.66666f + coef/3.0f; } else if ( hour < 18.0f ) { // between 9am and 6pm ambientColor = day; coef=1.0f; } else if ( hour < 19.0f ) { // between 6pm and 7pm coef = (hour - 18.0f); ambientColor = TCODColor::lerp(day,dawn2,coef); coef = 0.66666f + (1.0f-coef)/3.0f; } else if ( hour < 20.0f ) { // between 7pm and 8pm coef = (hour - 19.0f); ambientColor = TCODColor::lerp(dawn2,dawn,coef); coef = 0.33333f + (1.0f-coef)/3.0f; } else if ( hour < 21.0f ) { // between 8pm and 9pm coef = (hour - 20.0f); ambientColor = TCODColor::lerp(dawn,night,coef); coef = (1.0f-coef)/3.0f; } } libtcod-1.6.4+dfsg/samples/weather/util_weather.hpp000066400000000000000000000053771321276576200224200ustar00rootroot00000000000000/* * Copyright (c) 2010 Jice * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ class Weather { public : void init(int width, int height); void update(float elapsed); float getCloud(int x, int y); // 0.0 : dark cloud, 1.0 : no cloud float getLightning(int x, int y); // 0.0 : no lightning. 1.0 : full lightning light bool hasRainDrop(); // call for each cell on the map // when scrolling the map on the game side void move(int dx, int dy); // description of current weather const char *getWeather(); const TCODColor &getAmbientLightColor() { return ambientColor; } // timeInSecond : between 0 and 3600*24 void calculateAmbient(float timeInSeconds); // how fast the weather is changing. 0 : never changes, 1 : default > 1 : faster... void setChangeFactor(float f) { changeFactor = f; } // 0 : bad weather. 1 : good weather float getIndicator() { return indicator; } // to alter the weather float getIndicatorDelta() { return indicatorDelta; } void setIndicatorDelta(float v) { indicatorDelta=CLAMP(-1.0f,1.0f,v); } protected : typedef struct { int posx,posy; float intensity; // 0-1 float life; // in seconds int radius; // squared float noisex; } lightning_t; float indicator; // 0 : bad, 1 : good float indicatorDelta; float noisex,noisey; // position in the noise space float dx,dy; // sub cell cloud map position float changeFactor; TCODHeightMap *map; TCODList lightnings; TCODColor ambientColor; }; libtcod-1.6.4+dfsg/samples/worldgen/000077500000000000000000000000001321276576200173615ustar00rootroot00000000000000libtcod-1.6.4+dfsg/samples/worldgen/README.txt000066400000000000000000000003351321276576200210600ustar00rootroot00000000000000 World generator 0.1.0 Fast (< 1 sec for a 400×400 map) Heightmap, precipitation map, latitude-dependant temperature map, biome map Rain erosion Rapidely Exploring Random Tree rivers http://doryen.eptalys.net/demos/ libtcod-1.6.4+dfsg/samples/worldgen/main.cpp000066400000000000000000000127351321276576200210210ustar00rootroot00000000000000/* * Copyright (c) 2010 Jice * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "main.hpp" #define WIDTH 80 #define HEIGHT 50 TCODNoise noise1d(1); TCODNoise noise2d(2); WorldGenerator worldGen; // world map panning float wx=0,wy=0, curwx=0,curwy=0; // mouse coordinates in world map float mx=0,my=0; void update(float elapsed, TCOD_key_t k, TCOD_mouse_t mouse) { // destination wanted wx = (worldGen.getWidth()-2*WIDTH) * mouse.cx / WIDTH; wy = (worldGen.getHeight()-2*HEIGHT) * mouse.cy / HEIGHT; curwx += (wx-curwx)*elapsed; curwy += (wy-curwy)*elapsed; mx = curwx + mouse.cx*2; my = curwy + mouse.cy*2; worldGen.updateClouds(elapsed); } TCODColor getMapShadedColor(float worldX,float worldY,bool clouds) { // sun color static TCODColor sunCol(255,255,200); float wx = CLAMP(0.0f, worldGen.getWidth()-1,worldX); float wy = CLAMP(0.0f, worldGen.getHeight()-1,worldY); // apply cloud shadow float cloudAmount = clouds ? worldGen.getCloudThickness(wx,wy) : 0.0f; TCODColor col = worldGen.getInterpolatedColor(worldX,worldY); // apply sun light float intensity = worldGen.getInterpolatedIntensity(wx,wy); intensity = MIN(intensity, 1.5f-cloudAmount); int cr = (int)(intensity*(int)(col.r)*sunCol.r/255 ); int cg = (int)(intensity*(int)(col.g)*sunCol.g/255 ); int cb = (int)(intensity*(int)(col.b)*sunCol.b/255 ); TCODColor col2; col2.r = CLAMP(0,255,cr); col2.g = CLAMP(0,255,cg); col2.b = CLAMP(0,255,cb); col2.r=MAX(col2.r,col.r/2); col2.g=MAX(col2.g,col.g/2); col2.b=MAX(col2.b,col.b/2); return col2; } void render() { // subcell resolution image static TCODImage map(WIDTH*2,HEIGHT*2); // compute the map image for (int px=0; px <2*WIDTH; px++) { for (int py=0; py <2*HEIGHT; py++) { // world texel coordinate (with fisheye distorsion) float wx = px+curwx; float wy = py+curwy; map.putPixel(px,py,getMapShadedColor(wx,wy,true)); } } map.blit2x(TCODConsole::root,0,0); TCODConsole::root->setDefaultForeground(TCODColor::white); static const char *biomeNames[] = { "Tundra","Cold desert","Grassland", "Boreal forest", "Temperate forest", "Tropical/Montane forest", "Hot desert", "Savanna", "Tropical dry forest", "Tropical evergreen forest", "Thorn forest" }; if ( worldGen.isOnSea(mx,my) ) { // some information are irrelevant on sea TCODConsole::root->print(5,47,"Alt %5dm\n\nMove the mouse to scroll the map", (int)worldGen.getRealAltitude(mx,my) ); } else { TCODConsole::root->print(5,47,"Alt %5dm Prec %3dcm/sq. m/y Temp %d deg C\nBiome : %s\nMove the mouse to scroll the map", (int)worldGen.getRealAltitude(mx,my), (int)worldGen.getPrecipitations(mx,my), (int)worldGen.getTemperature(mx,my), biomeNames[worldGen.getBiome(mx,my)] ); } } int main (int argc, char *argv[]) { // initialize the game window TCODConsole::initRoot(WIDTH,HEIGHT,VERSION, false,TCOD_RENDERER_SDL); TCODSystem::setFps(25); TCODMouse::showCursor(true); TCOD_key_t k = {TCODK_NONE,0}; TCOD_mouse_t mouse; bool endCredits=false; // generate the world with all data (rain, temperature and so on...) worldGen.generate(NULL); // compute light intensity on ground (depends on light direction and ground slope) static float lightDir[3] = { 1.0f,1.0f,0.0f }; worldGen.computeSunLight(lightDir); while (! TCODConsole::isWindowClosed()) { // read keyboard // TCOD_key_t k=TCODConsole::checkForKeypress(TCOD_KEY_PRESSED|TCOD_KEY_RELEASED); // TCOD_mouse_t mouse=TCODMouse::getStatus(); TCODSystem::checkForEvent((TCOD_event_t)(TCOD_EVENT_KEY_PRESS|TCOD_EVENT_MOUSE),&k,&mouse); if ( k.vk == TCODK_PRINTSCREEN ) { // screenshot if (! k.pressed ) TCODSystem::saveScreenshot(NULL); k.vk=TCODK_NONE; } else if ( k.lalt && (k.vk == TCODK_ENTER || k.vk == TCODK_KPENTER) ) { // switch fullscreen if (! k.pressed ) TCODConsole::setFullscreen(!TCODConsole::isFullscreen()); k.vk=TCODK_NONE; } // update the game update(TCODSystem::getLastFrameLength(),k,mouse); // render the game screen render(); // render libtcod credits if (! endCredits ) endCredits = TCODConsole::renderCredits(4,4,true); // flush updates to screen TCODConsole::root->flush(); } return 0; } libtcod-1.6.4+dfsg/samples/worldgen/main.hpp000066400000000000000000000035251321276576200210230ustar00rootroot00000000000000/* * Copyright (c) 2010 Jice * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libtcod.hpp" #include "util_worldgen.hpp" #define VERSION "World generator v0.1.0" // console size #define CON_W 80 #define CON_H 50 #define IN_RECTANGLE(x,y,w,h) ((unsigned)(x) < (unsigned)(w) && (unsigned)(y) < (unsigned)(h)) #define SQRDIST(x1,y1,x2,y2) (((x1)-(x2))*((x1)-(x2))+((y1)-(y2))*((y1)-(y2))) #ifndef NDEBUG #define DBG(x) printf x #else #define DBG(x) #endif extern TCODNoise noise1d; extern TCODNoise noise2d; libtcod-1.6.4+dfsg/samples/worldgen/terminal.png000066400000000000000000000065451321276576200217140ustar00rootroot00000000000000PNG  IHDRL\sRGBbKGD pHYs  tIME $#)x IDATx]ˎCЀ ̒  q|Xrجʌr%X*+3Xp\.eYr\.{?5'[DŏroQL=J㿵˴WFO>VQ~NKXeK`u%gap IWFSfU8¼G2o;AYLz7'{#O}#f!(E %^̐9*.af_hߔc;0+CpR-=$,0>~7B2LJ"&AhF/QexK]Tl?)Kk܋/P5SsFT$k6kP}w[ubA!E T2FA1;@`1?4M 4=߉\LZ(`ݢbFzDqv_9:|(XU\h(.q35&\!VLA N`G-BJ#Ǐ d,x$"LAAV[s5/FU3y[[0,K,EDX&a#h|?= O̺ץDXz@U= ? h  -29ޮR2B #>W{ÌHY|l.t=-hSS6~\\炈i; rI)3[qj a=gsԔ. #7WrzNyH#OE\t=PrRԚu(QeШpd=`]x~oEAP?L◳bո*r"֨qrgIF1VUL$r >D:,Յf&v' nmQA(Oh$J5 b\b @qZ)Jeh6">$&d7TA R TRG|`u҆g8}Zh * hUNV/NfC[b[~NU2!4| yU=eR80c _"VG52wRйi0R5L~`T%]VqF4Zn C y͈=4AYfRxNg+?DRHd$˨oŹVXR#Fb+^$4TBG%$:?Q) 0bDU!)DSTXY!`ì}vav>d9)!|g<ҫRd8\SE|E5 iUQP_]n*~,$ث}Jh2LyzU靳]-RS9Y1La*HT)J8ܱn9wAbzbNlABxfjܩה¹S3brgWƓ-6N) Q՞P6Vꏇ_ym_d_崬Q4 86\S׆'ʬwIkHgfwv9/qd&\[*\*ZfdI|f=G{~_g;]֞(=`j)Lfpy_L_wvS;r^)WsZ5‚W.~7ǿ Xt\}^ox QjDiI}(;}fO|^;{}\kNKph0*5.,v~b?؋;Ζ/E4_\qQ j7v_>O-cIENDB`libtcod-1.6.4+dfsg/samples/worldgen/util_worldgen.cpp000066400000000000000000001271731321276576200227560ustar00rootroot00000000000000/* * Copyright (c) 2009 Jice * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY Jice ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL Jice BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // world generator // this was mostly generated with libtcod 1.4.2 heightmap tool ! #include #include #include "main.hpp" // temperature / precipitation Biome diagram (Whittaker diagram) EBiome biomeDiagram[5][5] = { // artic/alpine climate (below -5C) { TUNDRA, TUNDRA, TUNDRA, TUNDRA, TUNDRA, }, // cold climate (-5 / 5 C) { COLD_DESERT, GRASSLAND, BOREAL_FOREST, BOREAL_FOREST, BOREAL_FOREST, }, // temperate climate (5 / 15 C) { COLD_DESERT, GRASSLAND, TEMPERATE_FOREST, TEMPERATE_FOREST, TROPICAL_MONTANE_FOREST, }, // warm climate (15 - 20C) { HOT_DESERT, SAVANNA, TROPICAL_DRY_FOREST, TROPICAL_EVERGREEN_FOREST, TROPICAL_EVERGREEN_FOREST, }, // tropical climate (above 20 C) { HOT_DESERT, THORN_FOREST, TROPICAL_DRY_FOREST, TROPICAL_EVERGREEN_FOREST, TROPICAL_EVERGREEN_FOREST, }, }; static const float sandHeight=0.12f; static const float grassHeight=0.16f; //0.315f; static const float rockHeight=0.655f; static const float snowHeight=0.905f; //0.785f; // TCOD's land color map static const int MAX_COLOR_KEY=10; #define COLOR_KEY_MAX_SEA ((int)(sandHeight*255)-1) #define COLOR_KEY_MIN_LAND ((int)(sandHeight*255)) static const int keyIndex[MAX_COLOR_KEY] = {0, COLOR_KEY_MAX_SEA, COLOR_KEY_MIN_LAND, (int)(grassHeight*255), (int)(grassHeight*255)+10, (int)(rockHeight*255), (int)(rockHeight*255)+10, (int)(snowHeight*255), (int)(snowHeight*255)+10, 255 }; static const TCODColor keyColor[MAX_COLOR_KEY]= { TCODColor(0,0,50), // deep water TCODColor(20,20,200), // water-sand transition TCODColor(134,180,101),// sand TCODColor(80,120,10),// sand-grass transition TCODColor(17,109,7), // grass TCODColor(30,85,12), // grass-rock transisiton TCODColor(64,70,20), // rock TCODColor(120,140,40), // rock-snow transisiton TCODColor(208,208,239), // snow TCODColor(255,255,255) }; // altitude color map static const int MAX_ALT_KEY=8; static const int altIndexes[MAX_ALT_KEY] = { 0,15,(int)(sandHeight*255),(int)(sandHeight*255)+1, 80,130,195,255 }; static const float altitudes[MAX_ALT_KEY] = { -2000,-1000,-100,0,500,1000,2500,4000 // in meters }; static const TCODColor altColors[MAX_ALT_KEY]= { TCODColor(24,165,255), // -2000 TCODColor(132,214,255), // -1000 TCODColor(247,255,255), // -100 TCODColor(49,149,44), // 0 TCODColor(249,209,151), // 500 TCODColor(165,148,24), // 1000 TCODColor(153,110,6), // 2500 TCODColor(172,141,138), // 4000 }; // precipitation color map static const int MAX_PREC_KEY=19; static const int precIndexes[MAX_PREC_KEY] = { 4,8,12,16,20,24,28,32,36,40,50,60,70,80,100,120,140,160,255 }; static const float precipitations[MAX_PREC_KEY] = { 0,1,2,3,4,5,6,7,8,9,10,13,15,18,20,25,30,35,40 // cm / m / year }; static const TCODColor precColors[MAX_PREC_KEY]= { TCODColor(128,0,0), // < 4 TCODColor(173,55,0), // 4-8 TCODColor(227,102,0), // 8-12 TCODColor(255,149,0), // 12-16 TCODColor(255,200,0), // 16-20 TCODColor(255,251,0), // 20-24 TCODColor(191,255,0), // 24-28 TCODColor(106,251,0), // 28-32 TCODColor(25,255,48), // 32-36 TCODColor(48,255,141), // 36-40 TCODColor(28,255,232), // 40-50 TCODColor(54,181,255), // 50-60 TCODColor(41,71,191), // 60-70 TCODColor(38,0,255), // 70-80 TCODColor(140,0,255), // 80-100 TCODColor(221,0,255), // 100-120 TCODColor(255,87,255), // 120-140 TCODColor(255,173,255), // 140-160 TCODColor(255,206,255), // > 160 }; // temperature color map static const int MAX_TEMP_KEY=7; static const int tempIndexes[MAX_TEMP_KEY] = {0,42,84,126,168,210,255}; static const int temperatures[MAX_TEMP_KEY] = {-30,-20,-10,0,10,20,30}; static const TCODColor tempKeyColor[MAX_TEMP_KEY]= { TCODColor(180,8,130), // -30 C TCODColor(32,1,139), // -20 C TCODColor(0,65,252),// -10 C TCODColor(37,255,236),// 0 C TCODColor(255,255,1), // 10 C TCODColor(255,29,4), // 20 C TCODColor(80,3,0), // 30 C }; int WorldGenerator::getWidth() const { return HM_WIDTH; } int WorldGenerator::getHeight() const { return HM_HEIGHT; } float WorldGenerator::getAltitude(int x, int y) const { return hm->getValue(x,y); } float WorldGenerator::getRealAltitude(float x, float y) const { int ih=(int)(256*getInterpolatedAltitude(x,y)); int idx; ih = CLAMP(0,255,ih); for (idx=0; idx < MAX_ALT_KEY-1; idx++) { if ( altIndexes[idx+1] > ih ) break; } float alt = altitudes[idx] + (altitudes[idx+1]-altitudes[idx]) * (ih-altIndexes[idx])/(altIndexes[idx+1]-altIndexes[idx]); return alt; } float WorldGenerator::getPrecipitations(float x, float y) const { int iprec=(int)(256*precipitation->getValue((int)x,(int)y)); int idx; iprec=CLAMP(0,255,iprec); for (idx=0; idx < MAX_PREC_KEY-1; idx++) { if ( precIndexes[idx+1] > iprec ) break; } float prec = precipitations[idx] + (precipitations[idx+1]-precipitations[idx]) * (iprec-precIndexes[idx])/(precIndexes[idx+1]-precIndexes[idx]); return prec; } float WorldGenerator::getTemperature(float x, float y) const { return temperature->getValue((int)x,(int)y); } EBiome WorldGenerator::getBiome(float x, float y) const { return biomeMap[(int)x+(int)y*HM_WIDTH]; } float WorldGenerator::getInterpolatedAltitude(float x, float y) const { return hm->getInterpolatedValue(x,y); } void WorldGenerator::getInterpolatedNormal(float x, float y, float n[3]) const { return hm2->getNormal(x,y,n,sandHeight); } float WorldGenerator::getSandHeight() const { return sandHeight; } bool WorldGenerator::isOnSea(float x, float y) const { return getInterpolatedAltitude(x,y) <= sandHeight; } void WorldGenerator::addHill(int nbHill, float baseRadius, float radiusVar, float height) { for (int i=0; i< nbHill; i++ ) { float hillMinRadius=baseRadius*(1.0f-radiusVar); float hillMaxRadius=baseRadius*(1.0f+radiusVar); float radius = wgRng->getFloat(hillMinRadius, hillMaxRadius); int xh = wgRng->getInt(0,HM_WIDTH-1); int yh = wgRng->getInt(0,HM_HEIGHT-1); hm->addHill((float)xh,(float)yh,radius,height); } } void WorldGenerator::setLandMass(float landMass, float waterLevel) { // fix land mass. We want a proportion of landMass above sea level #ifndef NDEBUG float t0=TCODSystem::getElapsedSeconds(); #endif int heightcount[256]; memset(heightcount,0,sizeof(heightcount)); for ( int x=0; x < HM_WIDTH; x++) { for (int y=0; y < HM_HEIGHT; y++) { float h=hm->getValue(x,y); int ih=(int)(h*255); ih = CLAMP(0,255,ih); heightcount[ih]++; } } int i=0, totalcount=0; while (totalcount < HM_WIDTH*HM_HEIGHT*(1.0f-landMass) ) { totalcount += heightcount[i]; i++; } float newWaterLevel=i/255.0f; float landCoef = (1.0f-waterLevel)/(1.0f-newWaterLevel); float waterCoef = waterLevel / newWaterLevel; // water level should be raised/lowered to newWaterLevel for ( int x=0; x < HM_WIDTH; x++) { for (int y=0; y < HM_HEIGHT; y++) { float h=hm->getValue(x,y); if ( h > newWaterLevel ) { h = waterLevel + (h-newWaterLevel)*landCoef; } else { h = h * waterCoef; } hm->setValue(x,y,h); } } #ifndef NDEBUG float t1=TCODSystem::getElapsedSeconds(); DBG((" Landmass... %g\n", t1-t0 )); #endif } // function building the heightmap void WorldGenerator::buildBaseMap() { float t0=TCODSystem::getElapsedSeconds(); addHill(600,16.0*HM_WIDTH/200,0.7,0.3); hm->normalize(); float t1=TCODSystem::getElapsedSeconds(); DBG((" Hills... %g\n", t1-t0 )); t0=t1; hm->addFbm(noise,2.20*HM_WIDTH/400,2.20*HM_WIDTH/400,0,0,10.0f,1.0,2.05); hm->normalize(); hm2->copy(hm); t1=TCODSystem::getElapsedSeconds(); DBG((" Fbm... %g\n", t1-t0 )); t0=t1; setLandMass(0.6f,sandHeight); // fix land/mountain ratio using x^3 curve above sea level for ( int x=0; x < HM_WIDTH; x++) { for (int y=0; y < HM_HEIGHT; y++) { float h=hm->getValue(x,y); if ( h >= sandHeight ) { float coef = (h-sandHeight) / (1.0f - sandHeight); h = sandHeight + coef * coef * coef * (1.0f - sandHeight); hm->setValue(x,y,h); } } } t1=TCODSystem::getElapsedSeconds(); DBG((" Flatten plains... %g\n", t1-t0 )); t0=t1; // we use a custom erosion algo //hm->rainErosion(15000*HM_WIDTH/400,0.03,0.01,wgRng); //t1=TCODSystem::getElapsedSeconds(); //DBG((" Erosion... %g\n", t1-t0 )); //t0=t1; // compute clouds float f[2]; for ( int x=0; x < HM_WIDTH; x++) { f[0] = 6.0f*((float)(x) / HM_WIDTH); for (int y=0; y < HM_HEIGHT; y++) { f[1] = 6.0f*((float)(y) / HM_HEIGHT); // clouds[x][y] = 0.5f * (1.0f + 0.8f * noise->getFbmSimplex(f,4.0f)); clouds[x][y] = 0.5f * (1.0f + 0.8f * noise->getFbm(f,4.0f,TCOD_NOISE_SIMPLEX)); } } t1=TCODSystem::getElapsedSeconds(); DBG((" Init clouds... %g\n", t1-t0 )); t0=t1; } // function blurring the heightmap void WorldGenerator::smoothMap() { // 3x3 kernel for smoothing operations static const int smoothKernelSize=9; static const int smoothKernelDx[9]={-1,0,1,-1,0,1,-1,0,1}; static const int smoothKernelDy[9]={-1,-1,-1,0,0,0,1,1,1}; static const float smoothKernelWeight[9]={2,8,2,8,20,8,2,8,2}; #ifndef NDEBUG float t0=TCODSystem::getElapsedSeconds(); #endif hm->kernelTransform(smoothKernelSize,smoothKernelDx,smoothKernelDy,smoothKernelWeight,-1000,1000); hm2->kernelTransform(smoothKernelSize,smoothKernelDx,smoothKernelDy,smoothKernelWeight,-1000,1000); hm->normalize(); #ifndef NDEBUG float t1=TCODSystem::getElapsedSeconds(); DBG((" Blur... %g\n", t1-t0 )); #endif } static const int dirx[9] = { 0, -1,0,1,-1,1,-1,0,1 }; static const int diry[9] = { 0, -1,-1,-1,0,0,1,1,1 }; static const float dircoef[9] = { 1.0f, 1.0f/1.414f, 1.0f, 1.0f/1.414f,1.0f,1.0f,1.0f/1.414f, 1.0f,1.0f/1.414f }; static const int oppdir[9] = {0, 8, 7, 6, 5, 4, 3, 2, 1 }; // erosion parameters #define EROSION_FACTOR 0.01f #define SEDIMENTATION_FACTOR 0.01f #define MAX_EROSION_ALT 0.9f #define MUDSLIDE_COEF 0.4f void WorldGenerator::erodeMap() { TCODHeightMap newMap(HM_WIDTH,HM_HEIGHT); for (int i=5; i != 0; i --) { // compute flow and slope maps map_data_t *md = mapData; for (int y=0; y < HM_HEIGHT; y++) { for (int x=0; x < HM_WIDTH; x++) { float h=hm->getValue(x,y); float hmin=h, hmax=h; int minDir=0, maxDir=0; for (int i=1; i< 9; i++ ) { int ix = x+dirx[i]; int iy = y+diry[i]; if ( IN_RECTANGLE(ix,iy,HM_WIDTH,HM_HEIGHT)) { float h2=hm->getValue(ix,iy); if ( h2 < hmin ) { hmin=h2; minDir=i; } else if ( h2 > hmax ) { hmax=h2; maxDir=i; } } } md->flowDir = minDir; md->upDir = maxDir; float slope = hmin - h; // this is negative slope *= dircoef[minDir]; md->slope = slope; md++; } } md=mapData; for (int y=0; y < HM_HEIGHT; y++) { for (int x=0; x < HM_WIDTH; x++) { float sediment=0.0f; bool end=false; int ix=x,iy=y; uint8_t oldFlow=md->flowDir; map_data_t *md2=md; while ( !end ) { float h = hm->getValue(ix,iy); if (h < sandHeight-0.01f) break; if ( md2->flowDir == oppdir[oldFlow] ) { h += SEDIMENTATION_FACTOR * sediment; hm->setValue(ix,iy,h); end = true; } else { // remember, slope is negative h += precipitation->getValue(ix,iy)* EROSION_FACTOR * md2->slope; h=MAX(h,sandHeight); sediment -= md2->slope; hm->setValue(ix,iy,h); oldFlow = md2->flowDir; ix += dirx[oldFlow]; iy += diry[oldFlow]; md2 = &mapData[ix+iy*HM_WIDTH]; } } md++; } } DBG( (" Erosion pass %d\n",i)); // mudslides (smoothing) float sandCoef = 1.0f/(1.0f-sandHeight); for (int x=0; x < HM_WIDTH; x++) { for (int y=0; y < HM_HEIGHT; y++) { float h=hm->getValue(x,y); if ( h < sandHeight-0.01f || h >= MAX_EROSION_ALT ) { newMap.setValue(x,y,h); continue; } float sumDelta1 = 0.0f, sumDelta2 = 0.0f; int nb1 = 1, nb2 = 1; for (int i=1; i < 9; i++ ) { int ix = x+dirx[i]; int iy = y+diry[i]; if ( IN_RECTANGLE(ix,iy,HM_WIDTH,HM_HEIGHT)) { float ih = hm->getValue(ix,iy); if ( ih < h ) { if ( i ==1 || i == 3 || i == 6 || i == 8 ) { // diagonal neighbour sumDelta1 += (ih - h)*0.4f; nb1++; } else { // adjacent neighbour sumDelta2 += (ih -h)*1.6f; nb2++; } } } } // average height difference with lower neighbours float dh = sumDelta1/nb1 + sumDelta2/nb2; dh *= MUDSLIDE_COEF; float hcoef=(h-sandHeight)* sandCoef; dh *= (1.0f-hcoef*hcoef*hcoef); // less smoothing at high altitudes newMap.setValue(x,y,h+dh); } } hm->copy(&newMap); } } // interpolated cloud thickness float WorldGenerator::getCloudThickness(float x, float y) const { x += cloudDx; int ix=(int)x; int iy=(int)y; int ix1 = MIN(HM_WIDTH-1,ix+1); int iy1 = MIN(HM_HEIGHT-1,iy+1); float fdx = x - ix; float fdy = y - iy; float v1 = clouds[ix][iy]; float v2 = clouds[ix1][iy]; float v3 = clouds[ix][iy1]; float v4 = clouds[ix1][iy1]; float vx1 = ((1.0f - fdx) * v1 + fdx * v2); float vx2 = ((1.0f - fdx) * v3 + fdx * v4); float v = ((1.0f - fdy) * vx1 + fdy * vx2); return v; } TCODColor WorldGenerator::getMapColor(float h) { int colorIdx; if ( h < sandHeight ) colorIdx = (int)(h/sandHeight * COLOR_KEY_MAX_SEA); else colorIdx = COLOR_KEY_MIN_LAND + (int)((h-sandHeight)/(1.0f-sandHeight) * (255-COLOR_KEY_MIN_LAND)); colorIdx=CLAMP(0,255,colorIdx); return mapGradient[colorIdx]; } void WorldGenerator::computeSunLight(float lightDir[3]) { for (int x=0; x < HM_WIDTH; x++) { for (int y=0; y < HM_HEIGHT; y++) { worldint[x+y*HM_WIDTH]=getMapIntensity(x+0.5f,y+0.5f,lightDir); } } } float WorldGenerator::getMapIntensity(float worldX,float worldY, float lightDir[3]) { // sun color & direction static const TCODColor sunCol(255,255,160); float normal[3]; float wx = CLAMP(0.0f, HM_WIDTH-1,worldX); float wy = CLAMP(0.0f, HM_HEIGHT-1,worldY); // apply sun light getInterpolatedNormal(wx,wy,normal); normal[2] *= 3.0f; float intensity = 0.75f - (normal[0]*lightDir[0]+normal[1]*lightDir[1]+normal[2]*lightDir[2])*0.75f; intensity=CLAMP(0.75f,1.5f,intensity); return intensity; } TCODColor WorldGenerator::getInterpolatedColor(float worldX,float worldY) { return getInterpolatedColor(worldmap,worldX,worldY); } TCODColor WorldGenerator::getInterpolatedColor(TCODImage *img,float x,float y) { int w,h; img->getSize(&w,&h); float wx = CLAMP(0.0f, w-1,x); float wy = CLAMP(0.0f, h-1,y); int iwx = (int)wx; int iwy = (int)wy; float dx = wx - iwx; float dy = wy - iwy; TCODColor colNW = img->getPixel(iwx,iwy); TCODColor colNE = (iwx < w-1 ? img->getPixel(iwx+1,iwy) : colNW); TCODColor colSW = (iwy < h-1 ? img->getPixel(iwx,iwy+1) : colNW); TCODColor colSE = (iwx < w-1 && iwy < h-1 ? img->getPixel(iwx+1,iwy+1) : colNW); TCODColor colN = TCODColor::lerp(colNW,colNE,dx); TCODColor colS = TCODColor::lerp(colSW,colSE,dx); TCODColor col = TCODColor::lerp(colN,colS,dy); return col; } float WorldGenerator::getInterpolatedIntensity(float worldX, float worldY) { return getInterpolatedFloat(worldint,worldX,worldY,HM_WIDTH,HM_HEIGHT); } void WorldGenerator::updateClouds(float elapsedTime) { cloudTotalDx += elapsedTime * 5; cloudDx += elapsedTime * 5; if ( cloudDx >= 1.0f ) { int colsToTranslate=(int)cloudDx; cloudDx -= colsToTranslate; // translate the cloud map for ( int x=colsToTranslate; x < HM_WIDTH; x++) { for (int y=0; y < HM_HEIGHT; y++) { clouds[x-colsToTranslate][y]=clouds[x][y]; } } // compute a new column float f[2]; float cdx = (int)cloudTotalDx ; for ( int x=HM_WIDTH-colsToTranslate; x < HM_WIDTH; x++) { for (int y=0; y < HM_HEIGHT; y++) { f[0] = 6.0f*((float)(x+cdx) / HM_WIDTH); f[1] = 6.0f*((float)(y) / HM_HEIGHT); // clouds[x][y] = 0.5f * (1.0f + 0.8f * noise->getFbmSimplex(f,4.0f)); clouds[x][y] = 0.5f * (1.0f + 0.8f * noise->getFbm(f,4.0f,TCOD_NOISE_SIMPLEX)); } } } } class RiverPathCbk : public ITCODPathCallback { public: float getWalkCost( int xFrom, int yFrom, int xTo, int yTo, void *userData ) const { WorldGenerator *world = (WorldGenerator *)userData; float h1=world->hm->getValue(xFrom,yFrom); float h2=world->hm->getValue(xTo,yTo); if ( h2 < sandHeight ) return 0.0f; // float f[2] = {xFrom*10.0f/HM_WIDTH,yFrom*10.0f/HM_HEIGHT}; // return (1.0f+h2-h1)*10+5*(1.0f+noise2d.getSimplex(f)); return (0.01f+h2-h1)*100; } }; /* void WorldGenerator::generateRivers() { static int riverId=0; static RiverPathCbk cbk; // static TCODPath *path=NULL; static TCODDijkstra *path=NULL; // the source int sx,sy; // the destination int dx=-1,dy=-1; // get a random point near the coast sx = wgRng->getInt(0,HM_WIDTH-1); sy = wgRng->getInt(0,HM_HEIGHT-1); float h = hm->getValue(sx,sy); while ( h < sandHeight - 0.02 || h >= sandHeight ) { sx++; if ( sx == HM_WIDTH ) { sx=0; sy++; if ( sy == HM_HEIGHT ) sy=0; } h = hm->getValue(sx,sy); } riverId++; // get a closes mountain point float minDist=1E10f; int minx = sx - HM_WIDTH/4; int maxx = sx + HM_WIDTH/4; int miny = sy - HM_HEIGHT/4; int maxy = sy + HM_HEIGHT/4; minx = MAX(0,minx); maxx = MIN(HM_WIDTH-1,maxx); miny = MAX(0,miny); maxy = MIN(HM_HEIGHT-1,maxy); h = MIN(snowHeight,h + wgRng->getFloat(0.1f,0.5f)); for (int y=miny; y < maxy; y++) { for (int x=minx; x < maxx; x++) { float dh=hm->getValue(x,y); if ( dh >= h ) { dx=x; dy=y; break; } } } if (! path) { // path = new TCODPath(HM_WIDTH,HM_HEIGHT,&cbk,this); path = new TCODDijkstra(HM_WIDTH,HM_HEIGHT,&cbk,this); } path->compute(dx,dy); // if ( dx >= 0 && path->compute(dx,dy,sx,sy) ) { if ( dx >= 0 ) { path->setPath(sx,sy) ; DBG( ("river : %d %d -> %d %d\n",sx,sy,dx,dy)); int x,y; while (path->walk(&x,&y)) { map_data_t *md=&mapData[x+y*HM_WIDTH]; if ( md->riverId != 0 ) break; md->riverId = riverId; } } } */ void WorldGenerator::generateRivers() { static int riverId=0; // the source int sx,sy; // the destination int dx,dy; // get a random point near the coast sx = wgRng->getInt(0,HM_WIDTH-1); sy = wgRng->getInt(HM_HEIGHT/5,4*HM_HEIGHT/5); float h = hm->getValue(sx,sy); while ( h < sandHeight - 0.02 || h >= sandHeight ) { sx++; if ( sx == HM_WIDTH ) { sx=0; sy++; if ( sy == HM_HEIGHT ) sy=0; } h = hm->getValue(sx,sy); } TCODList tree; TCODList randPt; tree.push(sx+sy*HM_WIDTH); riverId++; dx = sx; dy = sy; for (int i=0; i< wgRng->getInt(50,200); i++) { int rx = wgRng->getInt(sx-200,sx+200); int ry = wgRng->getInt(sy-200,sy+200); // if ( IN_RECTANGLE(rx,ry,HM_WIDTH,HM_HEIGHT) ) { // float h=hm->getValue(rx,ry); // if ( h >= sandHeight ) { randPt.push(rx+ry*HM_WIDTH); // } // } } for (int i=0; i < randPt.size(); i++) { int rx = randPt.get(i)%HM_WIDTH; int ry = randPt.get(i)/HM_WIDTH; float minDist=1E10; int bestx=-1,besty=-1; for (int j=0;j < tree.size(); j++) { int tx=tree.get(j)%HM_WIDTH; int ty=tree.get(j)/HM_WIDTH; float dist = (tx-rx)*(tx-rx)+(ty-ry)*(ty-ry); if ( dist < minDist) { minDist=dist; bestx=tx; besty=ty; } } TCODLine::init(bestx,besty,rx,ry); int len = 3,cx=bestx,cy=besty; map_data_t *md=&mapData[cx+cy*HM_WIDTH]; if (md->riverId == riverId ) md->riverId=0; do { md=&mapData[cx+cy*HM_WIDTH]; if (md->riverId > 0 ) return; float h=hm->getValue(cx,cy); if ( h >= sandHeight ) { md->riverId = riverId; precipitation->setValue(cx,cy,1.0f); } if (cx ==0 || cx == HM_WIDTH-1 || cy == 0 || cy == HM_HEIGHT-1 ) len = 0; else if (TCODLine::step(&cx,&cy)) len=0; len --; } while(len > 0 ); int newNode = cx+cy*HM_WIDTH; if (newNode != bestx+besty*HM_WIDTH ) { tree.push(newNode); } } } /* void WorldGenerator::generateRivers() { static int riverId=0; // the source int sx,sy; // the destination int dx,dy; // get a random point near the coast sx = wgRng->getInt(0,HM_WIDTH-1); sy = wgRng->getInt(HM_HEIGHT/5,4*HM_HEIGHT/5); float h = hm->getValue(sx,sy); map_data_t *md=&mapData[sx+sy*HM_WIDTH]; while ( md->riverId == 0 && (h < sandHeight - 0.02 || h >= sandHeight) ) { sx++; if ( sx == HM_WIDTH ) { sx=0; sy++; if ( sy == HM_HEIGHT ) sy=0; } h = hm->getValue(sx,sy); md=&mapData[sx+sy*HM_WIDTH]; } riverId++; dx = sx; dy = sy; DBG( ("source : %d %d\n",sx,sy)); // travel down to the see // get the hiwest point around current position bool deadEnd=false; int len=0; river_t *river=new river_t(); rivers.push(river); int maxlen=HM_WIDTH,lastdx=1,lastdy=1; do { int coord = sx + sy*HM_WIDTH; map_data_t *md=&mapData[coord]; if ( md->riverId != 0 ) { river_t *joined = rivers.get(md->riverId-1); int i=0; while (joined->coords.get(i) != coord ) i++; while ( i < joined->coords.size() ) { int newStrength=joined->strength.get(i)+1; joined->strength.set(newStrength,i); i++; } break; } md->riverId = riverId; md->riverLength = len++; river->coords.push(coord); river->strength.push(1); if ( md->upDir != 0 ) { lastdx=dirx[md->upDir]; sx += lastdx; lastdy=diry[md->upDir]; sy += lastdy; deadEnd=false; } else if ( deadEnd ) { break; } else { sx += lastdx; sy += lastdy; if ( ! IN_RECTANGLE(sx,sy,HM_WIDTH,HM_HEIGHT ) ) break; deadEnd=true; } h=hm->getValue(sx,sy); maxlen--; } while ( maxlen > 0 && h <= snowHeight); } */ EClimate WorldGenerator::getClimateFromTemp(float temp) { if ( temp <= -5 ) return ARTIC_ALPINE; if ( temp <= 5 ) return COLD; if ( temp <= 15 ) return TEMPERATE; if ( temp <= 20 ) return WARM; return TROPICAL; } float WorldGenerator::getInterpolatedFloat(float *arr,float x,float y, int width, int height) { float wx = CLAMP(0.0f, width-1,x); float wy = CLAMP(0.0f, height-1,y); int iwx = (int)wx; int iwy = (int)wy; float dx = wx - iwx; float dy = wy - iwy; float iNW = arr[iwx+iwy*width]; float iNE = (iwx < width-1 ? arr[iwx+1+iwy*width] : iNW); float iSW = (iwy < height-1 ? arr[iwx+(iwy+1)*width] : iNW); float iSE = (iwx < width-1 && iwy < height-1 ? arr[iwx+1+(iwy+1)*width] : iNW); float iN = (1.0f-dx)*iNW + dx*iNE; float iS = (1.0f-dx)*iSW + dx*iSE; return (1.0f-dy)*iN + dy * iS; } int WorldGenerator::getRiverStrength(int riverId) { //river_t *river = rivers.get(riverId-1); //return river->strength.get(river->strength.size()-1); return 2; } void WorldGenerator::computePrecipitations() { static const float waterAdd = 0.03f; static const float slopeCoef = 2.0f; static const float basePrecip = 0.01f; // precipitation coef when slope == 0 float t0=TCODSystem::getElapsedSeconds(); // north/south winds for (int diry=-1; diry <= 1; diry += 2 ) { for (int x=0; x < HM_WIDTH; x++) { float noisex = (float)(x)*5/HM_WIDTH; // float waterAmount=(1.0f+noise1d.getFbmSimplex(&noisex,3.0f)); float waterAmount=(1.0f+noise1d.getFbm(&noisex,3.0f,TCOD_NOISE_SIMPLEX)); int starty = (diry == -1 ? HM_HEIGHT-1 : 0); int endy = (diry == -1 ? -1 : HM_HEIGHT); for (int y=starty; y != endy; y += diry) { float h = hm->getValue(x,y); if ( h < sandHeight ) { waterAmount += waterAdd; } else if (waterAmount > 0.0f ){ float slope; if ( (unsigned)(y + diry) < (unsigned)HM_HEIGHT ) slope = hm->getValue(x,y+diry) - h; else slope = h - hm->getValue(x,y-diry); if ( slope >= 0.0f ) { float precip = waterAmount * (basePrecip + slope * slopeCoef); precipitation->setValue(x,y,precipitation->getValue(x,y)+precip); waterAmount -= precip; waterAmount = MAX(0.0f,waterAmount); } } } } } float t1=TCODSystem::getElapsedSeconds(); DBG((" North/south winds... %g\n", t1-t0 )); t0=t1; // east/west winds for (int dirx=-1; dirx <= 1; dirx += 2 ) { for (int y=0; y < HM_HEIGHT; y++) { float noisey = (float)(y)*5/HM_HEIGHT; // float waterAmount=(1.0f+noise1d.getFbmSimplex(&noisey,3.0f)); float waterAmount=(1.0f+noise1d.getFbm(&noisey,3.0f,TCOD_NOISE_SIMPLEX)); int startx = (dirx == -1 ? HM_WIDTH-1 : 0); int endx = (dirx == -1 ? -1 : HM_WIDTH); for (int x=startx; x != endx; x += dirx) { float h = hm->getValue(x,y); if ( h < sandHeight ) { waterAmount += waterAdd; } else if (waterAmount > 0.0f ){ float slope; if ( (unsigned)(x + dirx) < (unsigned)HM_WIDTH ) slope = hm->getValue(x+dirx,y) - h; else slope = h - hm->getValue(x-dirx,y); if ( slope >= 0.0f ) { float precip = waterAmount * (basePrecip + slope * slopeCoef); precipitation->setValue(x,y,precipitation->getValue(x,y)+precip); waterAmount -= precip; waterAmount = MAX(0.0f,waterAmount); } } } } } t1=TCODSystem::getElapsedSeconds(); DBG((" East/west winds... %g\n", t1-t0 )); t0=t1; float min,max; precipitation->getMinMax(&min,&max); // latitude impact for (int y=HM_HEIGHT/4; y < 3*HM_HEIGHT/4; y++) { // latitude (0 : equator, -1/1 : pole) float lat = (float)(y-HM_HEIGHT/4) * 2 / HM_HEIGHT ; float coef = sinf(2*3.1415926*lat ); for (int x=0; x < HM_WIDTH; x++) { float f[2] = { (float)(x)/HM_WIDTH, (float)(y)/HM_HEIGHT }; // float xcoef = coef + 0.5f*noise2d.getFbmSimplex(f,3.0f); float xcoef = coef + 0.5f*noise2d.getFbm(f,3.0f,TCOD_NOISE_SIMPLEX); float precip = precipitation->getValue(x,y); precip += (max-min) * xcoef * 0.1f; precipitation->setValue(x,y,precip); } } t1=TCODSystem::getElapsedSeconds(); DBG((" latitude... %g\n", t1-t0 )); t0=t1; // very fast blur by scaling down and up static const int factor=8; static const int smallWidth = (HM_WIDTH+factor-1)/factor; static const int smallHeight = (HM_HEIGHT+factor-1)/factor; float *lowResMap = new float[smallWidth * smallHeight]; memset(lowResMap,0,sizeof(float)*smallWidth*smallHeight); for (int x=0; x < HM_WIDTH; x++) { for (int y=0; y < HM_HEIGHT; y++) { float v = precipitation->getValue(x,y); int ix=x/factor; int iy=y/factor; lowResMap[ix + iy*smallWidth ] += v; } } float coef = 1.0f/factor; for (int x=0; x < HM_WIDTH; x++) { for (int y=0; y < HM_HEIGHT; y++) { float v=getInterpolatedFloat(lowResMap,x*coef,y*coef,smallWidth,smallHeight); precipitation->setValue(x,y,v); } } delete [] lowResMap; } void WorldGenerator::smoothPrecipitations() { float t0=TCODSystem::getElapsedSeconds(); // better quality polishing blur using a 5x5 kernel // faster than TCODHeightmap kernelTransform function TCODHeightMap temphm(HM_WIDTH, HM_HEIGHT); temphm.copy(precipitation); for (int i=4; i != 0; i--) { for (int x=0; x < HM_WIDTH; x++) { int minx = x - 2; int maxx = x + 2; int miny=0; int maxy=2; float sum=0.0f; int count=0; minx = MAX( 0, minx ); maxx = MIN( HM_WIDTH-1, maxx); // compute the kernel sum at x,0 for (int ix=minx; ix <= maxx; ix++) { for (int iy =miny; iy <= maxy; iy++) { sum += precipitation->getValue(ix,iy); count++; } } temphm.setValue(x,0,sum/count); for (int y=1; y < HM_HEIGHT; y++) { if ( y-2 >= 0 ) { // remove the top-line sum for (int ix=minx; ix <= maxx; ix++) { sum -= precipitation->getValue(ix,y-2); count--; } } if ( y+2 < HM_HEIGHT ) { // add the bottom-line sum for (int ix=minx; ix <= maxx; ix++) { sum += precipitation->getValue(ix,y+2); count++; } } temphm.setValue(x,y,sum/count); } } } precipitation->copy(&temphm); float t1=TCODSystem::getElapsedSeconds(); DBG((" Blur... %g\n", t1-t0 )); t0=t1; precipitation->normalize(); t1=TCODSystem::getElapsedSeconds(); DBG((" Normalization... %g\n", t1-t0 )); t0=t1; } void WorldGenerator::computeTemperaturesAndBiomes() { // temperature shift with altitude : -25C at 6000 m // mean temp at sea level : 25C at lat 0 5C at lat 45 -25C at lat 90 (sinusoide) float sandCoef=1.0f/(1.0f-sandHeight); float waterCoef=1.0f/sandHeight; for (int y=0; y < HM_HEIGHT; y++) { float lat = (float)(y-HM_HEIGHT/2) * 2 / HM_HEIGHT ; float latTemp = 0.5f*(1.0f+pow(sin(3.1415926*(lat+0.5f)),5)); // between 0 and 1 if ( latTemp > 0.0f) latTemp = sqrt(latTemp); latTemp = -30 + latTemp*60; for (int x=0; x < HM_WIDTH; x++) { float h0 = hm->getValue(x,y); float h = h0 - sandHeight; if (h < 0.0f ) h *= waterCoef; else h *= sandCoef; float altShift = -35 * h; float temp=latTemp+altShift; temperature->setValue(x,y,temp); float humid = precipitation->getValue(x,y); // compute biome EClimate climate = getClimateFromTemp(temp); int iHumid = (int)(humid * 5); iHumid = MIN(4,iHumid); EBiome biome = biomeDiagram[climate][iHumid]; biomeMap[x+y*HM_WIDTH]=biome; } } float min,max; temperature->getMinMax(&min,&max); DBG( ("Temperatures min/max: %g / %g\n",min,max)); } TCODColor WorldGenerator::getBiomeColor(EBiome biome,int x,int y) { static const TCODColor biomeColors[] = { // TUNDRA, TCODColor(200,240,255), // COLD_DESERT, TCODColor(180,210,210), // GRASSLAND, TCODColor::sea, // BOREAL_FOREST, TCODColor(14,93,43), // TEMPERATE_FOREST, TCODColor(44,177,83), // TROPICAL_MONTANE_FOREST, TCODColor(185,232,164), // HOT_DESERT, TCODColor(235,255,210), // SAVANNA, TCODColor(255,205,20), // TROPICAL_DRY_FOREST, TCODColor(60,130,40), // TROPICAL_EVERGREEN_FOREST, TCODColor::green, // THORN_FOREST, TCODColor(192,192,112), }; int r=0,g=0,b=0, count=1; r +=biomeColors[biome].r; g +=biomeColors[biome].g; b +=biomeColors[biome].b; for (int i = 0; i < 4; i++ ) { int ix=x+wgRng->getInt(-10,10); int iy=y+wgRng->getInt(-10,10); if ( IN_RECTANGLE(ix,iy,HM_WIDTH,HM_HEIGHT) ) { TCODColor c=biomeColors[biomeMap[ix+iy*HM_WIDTH]]; r+=c.r + wgRng->getInt(-10,10); g+=c.g + wgRng->getInt(-10,10); b+=c.b + wgRng->getInt(-10,10); count++; } } r/=count; g/=count; b/=count; r=CLAMP(0,255,r); g=CLAMP(0,255,g); b=CLAMP(0,255,b); return TCODColor(r,g,b); } void WorldGenerator::computeColors() { // alter map color using temperature & precipitation maps map_data_t *md=mapData; for (int y=0; y < HM_HEIGHT; y++) { for (int x=0; x < HM_WIDTH; x++) { float h=hm->getValue(x,y); float temp = temperature->getValue(x,y); EBiome biome = biomeMap[x+y*HM_WIDTH]; TCODColor c; if (h < sandHeight ) c = getMapColor(h); else { c = getMapColor(h); c=TCODColor::lerp(c,getBiomeColor(biome,x,y),0.5f); } // snow near poles temp += 10*(clouds[HM_WIDTH-1-x][HM_HEIGHT-1-y]); // cheap 2D noise ;) if ( temp < -10.0f && h < sandHeight ) worldmap->putPixel(x,y,TCODColor::lerp(TCODColor::white,c,0.3f)); else if ( temp < -8.0f && h < sandHeight ) worldmap->putPixel(x,y,TCODColor::lerp(TCODColor::white,c,0.3f + 0.7f * (10.0f+temp)/2.0f)); else if ( temp < -2.0f && h >= sandHeight) worldmap->putPixel(x,y,TCODColor::white); else if ( temp < 2.0f && h >= sandHeight ) { //TCODColor snow = mapGradient[(int)(snowHeight*255) + (int)((255 - (int)(snowHeight*255)) * (0.6f-temp)/0.4f)]; c = TCODColor::lerp(TCODColor::white,c,(temp+2)/4.0f); worldmap->putPixel(x,y,c); } else { worldmap->putPixel(x,y,c); } md++; } } // draw rivers /* for (river_t **it=rivers.begin(); it != rivers.end(); it++) { for (int i=0; i < (*it)->coords.size(); i++ ) { int coord = (*it)->coords.get(i); int strength = (*it)->strength.get(i); int x = coord % HM_WIDTH; int y = coord / HM_WIDTH; TCODColor c= worldmap->getPixel(x,y); c = TCODColor::lerp(c,TCODColor::blue,(float)(strength)/5.0f); worldmap->putPixel(x,y,c); } } */ md=mapData; for (int y=0; y < HM_HEIGHT; y++) { for (int x=0; x < HM_WIDTH; x++) { if ( md->riverId > 0 ) { TCODColor c= worldmap->getPixel(x,y); c = TCODColor::lerp(c,TCODColor::blue,0.3f); worldmap->putPixel(x,y,c); } md++; } } // blur static const int dx[]={0,-1,0,1,0}; static const int dy[]={0,0,-1,0,1}; static const int coef[]={1,2,2,2,2}; for (int x=0; x < HM_WIDTH; x++) { for (int y=0; y < HM_HEIGHT; y++) { int r=0,g=0,b=0,count=0; for (int i=0; i < 5; i++) { int ix=x+dx[i]; int iy=y+dy[i]; if (IN_RECTANGLE(ix,iy,HM_WIDTH,HM_HEIGHT)){ TCODColor c=worldmap->getPixel(ix,iy); r += coef[i]*c.r; g += coef[i]*c.g; b += coef[i]*c.b; count += coef[i]; } } r /= count; g /= count; b /= count; worldmap->putPixel(x,y,TCODColor(r,g,b)); } } drawCoasts(worldmap); } void WorldGenerator::generate(TCODRandom *wRng) { float t00,t0=TCODSystem::getElapsedSeconds(); t00=t0; cloudDx=cloudTotalDx=0.0f; TCODColor::genMap(mapGradient,MAX_COLOR_KEY,keyColor,keyIndex); if ( wRng == NULL ) wRng=TCODRandom::getInstance(); wgRng = wRng; noise=new TCODNoise(2,wgRng); hm=new TCODHeightMap(HM_WIDTH,HM_HEIGHT); hm2=new TCODHeightMap(HM_WIDTH,HM_HEIGHT); worldmap = new TCODImage(HM_WIDTH,HM_HEIGHT); worldint = new float[HM_WIDTH*HM_HEIGHT]; temperature = new TCODHeightMap(HM_WIDTH,HM_HEIGHT); precipitation = new TCODHeightMap(HM_WIDTH,HM_HEIGHT); biomeMap = new EBiome[HM_WIDTH*HM_HEIGHT]; mapData = new map_data_t[HM_WIDTH*HM_HEIGHT]; memset(mapData,0,sizeof(map_data_t)*HM_WIDTH*HM_HEIGHT); float t1=TCODSystem::getElapsedSeconds(); DBG(("Initialization... %g\n", t1-t0 )); t0=t1; buildBaseMap(); t1=TCODSystem::getElapsedSeconds(); DBG(("Heightmap construction... %g\n", t1-t0 )); t0=t1; computePrecipitations(); t1=TCODSystem::getElapsedSeconds(); DBG(("Precipitation map... %g\n", t1-t0 )); t0=t1; erodeMap(); t1=TCODSystem::getElapsedSeconds(); DBG(("Erosion... %g\n", t1-t0 )); t0=t1; smoothMap(); t1=TCODSystem::getElapsedSeconds(); DBG(("Smooth... %g\n", t1-t0 )); t0=t1; setLandMass(0.6f,sandHeight); for (int i=0; i < HM_WIDTH*HM_HEIGHT/3000; i++) { // for (int i=0; i < 1; i++) { generateRivers(); } t1=TCODSystem::getElapsedSeconds(); DBG(("Rivers... %g\n", t1-t0 )); t0=t1; smoothPrecipitations(); t1=TCODSystem::getElapsedSeconds(); DBG(("Smooth precipitations... %g\n", t1-t0 )); t0=t1; computeTemperaturesAndBiomes(); t1=TCODSystem::getElapsedSeconds(); DBG(("Temperature map... %g\n", t1-t0 )); t0=t1; computeColors(); t1=TCODSystem::getElapsedSeconds(); DBG(("Color map... %g\n", t1-t0 )); t0=t1; t1=TCODSystem::getElapsedSeconds(); DBG(("TOTAL TIME... %g\n", t1-t00 )); } void WorldGenerator::drawCoasts(TCODImage *img) { // detect coasts for (int x=0; x < HM_WIDTH-1; x++) { for (int y=0; y < HM_HEIGHT-1; y++) { float h = hm->getValue(x,y); float h2 = hm->getValue(x+1,y); if ( ( h < sandHeight && h2 >= sandHeight ) || ( h2 < sandHeight && h >= sandHeight ) ) img->putPixel(x,y,TCODColor::black); else { h = hm->getValue(x,y); h2 = hm->getValue(x,y+1); if ( ( h < sandHeight && h2 >= sandHeight ) || ( h2 < sandHeight && h >= sandHeight ) ) img->putPixel(x,y,TCODColor::black); } } } } void WorldGenerator::saveBiomeMap(const char *filename) { static TCODImage *legend=NULL; static int legendHeight,legendWidth; static const TCODColor biomeColors[] = { // TUNDRA, TCODColor(88,234,250), // COLD_DESERT, TCODColor(129,174,170), // GRASSLAND, TCODColor::sea, // BOREAL_FOREST, TCODColor(14,93,43), // TEMPERATE_FOREST, TCODColor(44,177,83), // TROPICAL_MONTANE_FOREST, TCODColor(185,232,164), // HOT_DESERT, TCODColor(229,247,184), // SAVANNA, TCODColor::orange, // TROPICAL_DRY_FOREST, TCODColor::darkYellow, // TROPICAL_EVERGREEN_FOREST, TCODColor::green, // THORN_FOREST, TCODColor(192,192,112), }; if ( legend == NULL ) { legend = new TCODImage("data/img/legend_biome.png"); legend->getSize(&legendWidth,&legendHeight); } if ( filename == NULL ) filename="world_biome.png"; TCODImage img(MAX(HM_WIDTH,legendWidth),HM_HEIGHT+legendHeight); // draw biome map for (int x=0; x < HM_WIDTH; x++) { for (int y=0; y < HM_HEIGHT; y++) { float h=hm->getValue(x,y); if ( h < sandHeight ) img.putPixel(x,y,TCODColor(100,100,255)); else img.putPixel(x,y,biomeColors[biomeMap[x+y*HM_WIDTH]]); } } drawCoasts(&img); // blit legend int legendx = MAX(HM_WIDTH,legendWidth) / 2 - legendWidth/2; for (int x=0; x < legendWidth; x++) { for (int y=0; y < legendHeight; y++) { img.putPixel(legendx+x,HM_HEIGHT+y,legend->getPixel(x,y)); } } // fill legend colors for (int i=0; i < 6; i++ ) { for (int x=17; x < 47; x++) for (int y=4+i*14; y < 14+i*14; y++ ) img.putPixel(legendx+x,HM_HEIGHT+y,biomeColors[i]); } for (int i=6; i < NB_BIOMES; i++ ) { for (int x=221; x < 251; x++) for (int y=4+(i-6)*14; y < 14+(i-6)*14; y++ ) img.putPixel(legendx+x,HM_HEIGHT+y,biomeColors[i]); } img.save(filename); } void WorldGenerator::saveTemperatureMap(const char *filename) { static TCODColor tempGradient[256]; static TCODImage *legend=NULL; static int legendHeight,legendWidth; if ( legend == NULL ) { legend = new TCODImage("data/img/legend_temperature.png"); legend->getSize(&legendWidth,&legendHeight); TCODColor::genMap(tempGradient,MAX_TEMP_KEY,tempKeyColor,tempIndexes); } if ( filename == NULL ) filename="world_temperature.png"; TCODImage img(MAX(HM_WIDTH,legendWidth),HM_HEIGHT+legendHeight); float minTemp,maxTemp; temperature->getMinMax(&minTemp,&maxTemp); // render temperature map for (int x=0; x < HM_WIDTH; x++) { for (int y=0; y < HM_HEIGHT; y++) { float h=hm->getValue(x,y); if ( h < sandHeight ) img.putPixel(x,y,TCODColor(100,100,255)); else { float temp=temperature->getValue(x,y); temp = (temp - minTemp) / (maxTemp-minTemp); int colorIdx = (int)(temp*255); colorIdx=CLAMP(0,255,colorIdx); img.putPixel(x,y,tempGradient[colorIdx]); } } } drawCoasts(&img); // blit legend int legendx = MAX(HM_WIDTH,legendWidth) / 2 - legendWidth/2; for (int x=0; x < legendWidth; x++) { for (int y=0; y < legendHeight; y++) { img.putPixel(legendx+x,HM_HEIGHT+y,legend->getPixel(x,y)); } } img.save(filename); } void WorldGenerator::savePrecipitationMap(const char *filename) { static TCODImage *legend=NULL; static int legendHeight,legendWidth; if ( legend == NULL ) { legend = new TCODImage("data/img/legend_precipitation.png"); legend->getSize(&legendWidth,&legendHeight); } if ( filename == NULL ) filename="world_precipitation.png"; TCODImage img(MAX(HM_WIDTH,legendWidth),HM_HEIGHT+legendHeight); // render precipitation map for (int x=0; x < HM_WIDTH; x++) { for (int y=0; y < HM_HEIGHT; y++) { float h=hm->getValue(x,y); if ( h < sandHeight ) img.putPixel(x,y,TCODColor(100,100,255)); else { float prec=precipitation->getValue(x,y); int iprec = (int)(prec * 180); int colorIdx=0; while (colorIdx < MAX_PREC_KEY && iprec > precIndexes[colorIdx]) colorIdx++; colorIdx = CLAMP(0,MAX_PREC_KEY,colorIdx); img.putPixel(x,y,precColors[colorIdx]); } } } drawCoasts(&img); // blit legend int legendx = MAX(HM_WIDTH,legendWidth) / 2 - legendWidth/2; for (int x=0; x < legendWidth; x++) { for (int y=0; y < legendHeight; y++) { img.putPixel(legendx+x,HM_HEIGHT+y,legend->getPixel(x,y)); } } img.save(filename); } void WorldGenerator::saveAltitudeMap(const char *filename) { static TCODColor altGradient[256]; static TCODImage *legend=NULL; static int legendHeight,legendWidth; if ( legend == NULL ) { legend = new TCODImage("data/img/legend_altitude.png"); legend->getSize(&legendWidth,&legendHeight); TCODColor::genMap(altGradient,MAX_ALT_KEY,altColors,altIndexes); } if ( filename == NULL ) filename="world_altitude.png"; TCODImage img(HM_WIDTH+legendWidth,MAX(HM_HEIGHT,legendHeight)); // render altitude map for (int x=0; x < HM_WIDTH; x++) { for (int y=0; y < HM_HEIGHT; y++) { float h=hm->getValue(x,y); int ialt = (int)(h * 256); ialt = CLAMP(0,255,ialt); img.putPixel(x,y,altGradient[ialt]); } } // blit legend int legendy = MAX(HM_HEIGHT,legendHeight) / 2 - legendHeight/2; for (int x=0; x < legendWidth; x++) { for (int y=0; y < legendHeight; y++) { img.putPixel(HM_WIDTH+x,legendy+y,legend->getPixel(x,y)); } } img.save(filename); } libtcod-1.6.4+dfsg/samples/worldgen/util_worldgen.hpp000066400000000000000000000120161321276576200227500ustar00rootroot00000000000000/* * Copyright (c) 2009 Jice * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY Jice ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL Jice BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // size of the heightmap #define HM_WIDTH 400 #define HM_HEIGHT 400 // biome and climate list. based on Whittaker Biome Diagram enum EClimate { ARTIC_ALPINE, COLD, TEMPERATE, WARM, TROPICAL, NB_CLIMATES }; // grassland : might be either grassland, shrubland or woodland depending on the vegetation level // savanna : might be either savanna or thorn forest depending on the vegetation level enum EBiome {TUNDRA, COLD_DESERT, GRASSLAND, BOREAL_FOREST, TEMPERATE_FOREST, TROPICAL_MONTANE_FOREST, HOT_DESERT, SAVANNA, TROPICAL_DRY_FOREST, TROPICAL_EVERGREEN_FOREST, THORN_FOREST, NB_BIOMES }; class WorldGenerator { public : // altitude->color map TCODColor mapGradient[256]; // world height map (0.0 - 1.0) TCODHeightMap *hm; // height map without erosion TCODHeightMap *hm2; // complete world map (not shaded) TCODImage *worldmap; // temperature map (in C) TCODHeightMap *temperature; // precipitation map (0.0 - 1.0) TCODHeightMap *precipitation; // biome map EBiome *biomeMap; void generate(TCODRandom *wRng); // getters int getWidth() const; int getHeight() const; float getAltitude(int x, int y) const; // heightmap. between 0 and 1 float getInterpolatedAltitude(float x, float y) const; float getSandHeight() const; bool isOnSea(float x, float y) const; float getCloudThickness(float x, float y) const; void getInterpolatedNormal(float x, float y, float n[3]) const; TCODColor getInterpolatedColor(float worldX,float worldY); float getInterpolatedIntensity(float worldX, float worldY); // update void updateClouds(float elapsedTime); void computeSunLight(float lightDir[3]); // data float getRealAltitude(float x, float y) const; // altitude in meters float getPrecipitations(float x, float y) const; // in centimeter/m/year float getTemperature(float x, float y) const; // in C EBiome getBiome(float x, float y) const; // map generators void saveBiomeMap(const char *filename = NULL); void saveAltitudeMap(const char *filename = NULL); void saveTemperatureMap(const char *filename = NULL); void savePrecipitationMap(const char *filename = NULL); protected : friend class RiverPathCbk; TCODNoise *noise; // cloud thickness float clouds[HM_WIDTH][HM_HEIGHT]; float cloudDx; // horizontal offset for smooth scrolling float cloudTotalDx; // world light intensity map (shadow map) float *worldint; typedef struct { float slope; // number of cells flowing into this cell uint32_t area; // direction of lowest neighbour uint8_t flowDir; // inverse flow direction uint8_t upDir; uint8_t inFlags; // incoming flows uint8_t riverId; int riverLength; } map_data_t; map_data_t * mapData; typedef struct { TCODList coords; TCODList strength; } river_t; TCODList rivers; TCODRandom *wgRng; void addHill(int nbHill, float baseRadius, float radiusVar, float height); void buildBaseMap(); void erodeMap(); void smoothMap(); // compute the ground color from the heightmap TCODColor getMapColor(float h); // get sun light intensity on a point of the map float getMapIntensity(float worldX,float worldY, float lightDir[3]); TCODColor getInterpolatedColor(TCODImage *img,float x,float y); float getInterpolatedFloat(float *arr,float x,float y, int width, int height); void generateRivers(); void smoothPrecipitations() ; int getRiverStrength(int riverId); void setLandMass(float percent, float waterLevel); void computeTemperaturesAndBiomes(); TCODColor getBiomeColor(EBiome biome,int x,int y); void computePrecipitations(); void computeColors(); void drawCoasts(TCODImage *img); EClimate getClimateFromTemp(float temp); }; libtcod-1.6.4+dfsg/src/000077500000000000000000000000001321276576200146635ustar00rootroot00000000000000libtcod-1.6.4+dfsg/src/README.txt000066400000000000000000000041001321276576200163540ustar00rootroot00000000000000This is the Doryen library source code. libtcod.h and libtcod.hpp are the main headers, included respectively by the C and C++ programs that use libtcod. Each "toolkit" is in a separate file set. For each toolkit, you may have : * include/.h : the C header * include/.hpp : the C++ header * src/_c.c : the C source code that contains the actual implementation * src/.cpp : the C++ wrapper Current toolkits : bresenham : line drawing using the Bresenham algorithm. bsp : binary space partition tree module color : 24 bits colors operations. console : true color console emulator. It relies on some private functions of the sys toolkit. fov : field of view calculator. heightmap : heightmap toolkit. image : image manipulation. It relies on some private functions of the sys toolkit. list : a fast and lightweight generic container (faster than STL). mersenne : pseudorandom number generator using the Mersenne twister algorithm. mouse : mouse support. namegen : name generator noise : various noise generators. parser : config file parser. path : path finding module. sys : system specific functions. txtfield : work-in-progress text input utility zip : compression module Note that some of the sys toolkits rely on system dependent functions. They have currently a single working implementation relying on SDL : sys_sdl_c.c As it is heavily system dependent, the mouse C implementation is in sys_sdl_c.c. As of 1.4, the image load/save functions are isolated in sys_sdl_XXX.c, XXX being the image type (currently bmp and png). As of 1.5.1, sys_opengl_c.c contains OpenGL and GLSL renderers. Those two renderers are still dependent on SDL. libtcod_int.h contains everything that is exported by the toolkits (implemented in a toolkit and used in another one) but should not be seen by the user of the library. These are the private (or undocumented) modules : lex : a generic lexical parser. tree : a minimalist tree toolkit. sys : sys also contains an undocumented threading toolkit. libtcod-1.6.4+dfsg/src/bresenham.cpp000066400000000000000000000041321321276576200173330ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include // ********** bresenham line drawing ********** void TCODLine::init(int xFrom, int yFrom, int xTo, int yTo) { TCOD_line_init(xFrom,yFrom,xTo,yTo); } bool TCODLine::step(int *xCur, int *yCur) { return TCOD_line_step(xCur,yCur) != 0; } static TCODLineListener *listener=NULL; // C to C++ bridge extern "C" bool internalListener(int x,int y) { return listener->putPoint(x,y) ? 1 : 0; } bool TCODLine::line(int xFrom, int yFrom, int xTo, int yTo, TCODLineListener *plistener) { listener=plistener; return TCOD_line(xFrom,yFrom,xTo,yTo,internalListener) != 0; } libtcod-1.6.4+dfsg/src/bresenham_c.c000066400000000000000000000070401321276576200172760ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include static TCOD_bresenham_data_t bresenham_data; /* ********** bresenham line drawing ********** */ void TCOD_line_init_mt(int xFrom, int yFrom, int xTo, int yTo, TCOD_bresenham_data_t *data) { data->origx=xFrom; data->origy=yFrom; data->destx=xTo; data->desty=yTo; data->deltax=xTo - xFrom; data->deltay=yTo - yFrom; if ( data->deltax > 0 ) { data->stepx=1; } else if ( data->deltax < 0 ){ data->stepx=-1; } else data->stepx=0; if ( data->deltay > 0 ) { data->stepy=1; } else if ( data->deltay < 0 ){ data->stepy=-1; } else data->stepy = 0; if ( data->stepx*data->deltax > data->stepy*data->deltay ) { data->e = data->stepx*data->deltax; data->deltax *= 2; data->deltay *= 2; } else { data->e = data->stepy*data->deltay; data->deltax *= 2; data->deltay *= 2; } } bool TCOD_line_step_mt(int *xCur, int *yCur, TCOD_bresenham_data_t *data) { if ( data->stepx*data->deltax > data->stepy*data->deltay ) { if ( data->origx == data->destx ) return true; data->origx+=data->stepx; data->e -= data->stepy*data->deltay; if ( data->e < 0) { data->origy+=data->stepy; data->e+=data->stepx*data->deltax; } } else { if ( data->origy == data->desty ) return true; data->origy+=data->stepy; data->e -= data->stepx*data->deltax; if ( data->e < 0) { data->origx+=data->stepx; data->e+=data->stepy*data->deltay; } } *xCur=data->origx; *yCur=data->origy; return false; } bool TCOD_line_mt(int xo, int yo, int xd, int yd, TCOD_line_listener_t listener, TCOD_bresenham_data_t *data) { TCOD_line_init_mt(xo,yo,xd,yd,data); do { if (! listener(xo,yo)) return false; } while (! TCOD_line_step_mt(&xo,&yo,data)); return true; } void TCOD_line_init(int xFrom, int yFrom, int xTo, int yTo) { TCOD_line_init_mt(xFrom,yFrom,xTo,yTo,&bresenham_data); } bool TCOD_line_step(int *xCur, int *yCur) { return TCOD_line_step_mt(xCur,yCur,&bresenham_data); } bool TCOD_line(int xo, int yo, int xd, int yd, TCOD_line_listener_t listener) { return TCOD_line_mt(xo,yo,xd,yd,listener,&bresenham_data); } libtcod-1.6.4+dfsg/src/bsp.cpp000066400000000000000000000133111321276576200161520ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include TCODBsp::TCODBsp(TCODBsp *father, bool left) { if ( father->horizontal ) { x=father->x; w=father->w; y = left ? father->y : father->position; h = left ? father->position - y: father->y + father->h - father->position; } else { y=father->y; h=father->h; x = left ? father->x : father->position; w = left ? father->position - x: father->x + father->w - father->position; } level=father->level+1; } TCODBsp::~TCODBsp() { removeSons(); } bool TCODBsp::traversePreOrder(ITCODBspCallback *listener, void *userData) { if (!listener->visitNode(this,userData)) return false; if ( getLeft() && !getLeft()->traversePreOrder(listener,userData) ) return false; if ( getRight() && !getRight()->traversePreOrder(listener,userData)) return false; return true; } bool TCODBsp::traverseInOrder(ITCODBspCallback *listener, void *userData) { if ( getLeft() && !getLeft()->traverseInOrder(listener,userData) ) return false; if (!listener->visitNode(this,userData)) return false; if ( getRight() && !getRight()->traverseInOrder(listener,userData)) return false; return true; } bool TCODBsp::traversePostOrder(ITCODBspCallback *listener,void *userData) { if ( getLeft() && !getLeft()->traversePostOrder(listener,userData)) return false; if ( getRight() && !getRight()->traversePostOrder(listener,userData)) return false; if (!listener->visitNode(this,userData)) return false; return true; } bool TCODBsp::traverseLevelOrder(ITCODBspCallback *listener, void *userData) { TCODList stack; stack.push(this); while ( ! stack.isEmpty() ) { TCODBsp *node=stack.get(0); stack.remove(node); if ( node->getLeft() ) stack.push(node->getLeft()); if ( node->getRight() ) stack.push(node->getRight()); if (!listener->visitNode(node,userData)) return false; } return true; } bool TCODBsp::traverseInvertedLevelOrder(ITCODBspCallback *listener, void *userData) { TCODList stack1; TCODList stack2; stack1.push(this); while ( ! stack1.isEmpty() ) { TCODBsp *node=stack1.get(0); stack2.push(node); stack1.remove(node); if ( node->getLeft() ) stack1.push(node->getLeft()); if ( node->getRight() ) stack1.push(node->getRight()); } while ( ! stack2.isEmpty() ) { TCODBsp *node=stack2.pop(); if (!listener->visitNode(node,userData)) return false; } return true; } void TCODBsp::removeSons() { TCODBsp *node=(TCODBsp *)sons; while ( node ) { TCODBsp *nextNode=(TCODBsp *)node->next; node->removeSons(); delete node; node=nextNode; } sons=NULL; } void TCODBsp::splitOnce(bool horizontal, int position) { this->horizontal = horizontal; this->position=position; addSon(new TCODBsp(this,true)); addSon(new TCODBsp(this,false)); } void TCODBsp::splitRecursive(TCODRandom *randomizer, int nb, int minHSize, int minVSize, float maxHRatio, float maxVRatio) { if ( nb == 0 || (w < 2*minHSize && h < 2*minVSize ) ) return; bool horiz; if (! randomizer ) randomizer=TCODRandom::getInstance(); // promote square rooms if ( h < 2*minVSize || w > h * maxHRatio ) horiz = false; else if ( w < 2*minHSize || h > w * maxVRatio) horiz = true; else horiz = randomizer->getInt(0,1) == 0; int position; if ( horiz ) { position = randomizer->getInt(y+minVSize,y+h-minVSize); } else { position = randomizer->getInt(x+minHSize,x+w-minHSize); } splitOnce(horiz,position); getLeft()->splitRecursive(randomizer,nb-1,minHSize,minVSize,maxHRatio,maxVRatio); getRight()->splitRecursive(randomizer,nb-1,minHSize,minVSize,maxHRatio,maxVRatio); } void TCODBsp::resize(int x,int y, int w, int h) { this->x=x; this->y=y; this->w=w; this->h=h; if ( getLeft() ) { if ( horizontal ) { getLeft()->resize(x,y,w,position-y); getRight()->resize(x,position,w,y+h-position); } else { getLeft()->resize(x,y,position-x,h); getRight()->resize(position,y,x+w-position,h); } } } bool TCODBsp::contains(int px, int py) const { return (px >= x && py >= y && px < x+w && py < y+h); } TCODBsp *TCODBsp::findNode(int px, int py) { if ( ! contains(px,py) ) return NULL; if ( ! isLeaf() ) { TCODBsp *left,*right; left=getLeft(); if ( left->contains(px,py) ) return left->findNode(px,py); right=getRight(); if ( right->contains(px,py) ) return right->findNode(px,py); } return this; } libtcod-1.6.4+dfsg/src/bsp_c.c000066400000000000000000000175761321276576200161350ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include TCOD_bsp_t *TCOD_bsp_new(void) { return (TCOD_bsp_t *)calloc(sizeof(TCOD_bsp_t),1); } TCOD_bsp_t *TCOD_bsp_new_with_size(int x,int y,int w, int h) { TCOD_bsp_t *bsp=(TCOD_bsp_t *)calloc(sizeof(TCOD_bsp_t),1); bsp->x=x; bsp->y=y; bsp->w=w; bsp->h=h; return bsp; } TCOD_bsp_t * TCOD_bsp_left(TCOD_bsp_t *node) { return (TCOD_bsp_t *)node->tree.sons; } TCOD_bsp_t * TCOD_bsp_right(TCOD_bsp_t *node) { return node->tree.sons ? (TCOD_bsp_t *)node->tree.sons->next : NULL; } TCOD_bsp_t * TCOD_bsp_father(TCOD_bsp_t *node) { return (TCOD_bsp_t *)node->tree.father; } bool TCOD_bsp_is_leaf(TCOD_bsp_t *node) { return node->tree.sons==NULL; } void TCOD_bsp_delete(TCOD_bsp_t *node) { TCOD_bsp_remove_sons(node); free(node); } static TCOD_bsp_t *TCOD_bsp_new_intern(TCOD_bsp_t *father, bool left) { TCOD_bsp_t *bsp=(TCOD_bsp_t *)calloc(sizeof(TCOD_bsp_t),1); if ( father->horizontal ) { bsp->x=father->x; bsp->w=father->w; bsp->y = left ? father->y : father->position; bsp->h = left ? father->position - bsp->y: father->y + father->h - father->position; } else { bsp->y=father->y; bsp->h=father->h; bsp->x = left ? father->x : father->position; bsp->w = left ? father->position - bsp->x: father->x + father->w - father->position; } bsp->level=father->level+1; return bsp; } bool TCOD_bsp_traverse_pre_order(TCOD_bsp_t *node, TCOD_bsp_callback_t listener, void *userData) { if (!listener(node,userData)) return false; if ( TCOD_bsp_left(node) && !TCOD_bsp_traverse_pre_order(TCOD_bsp_left(node),listener,userData)) return false; if ( TCOD_bsp_right(node) && !TCOD_bsp_traverse_pre_order(TCOD_bsp_right(node),listener,userData)) return false; return true; } bool TCOD_bsp_traverse_in_order(TCOD_bsp_t *node, TCOD_bsp_callback_t listener, void *userData) { if ( TCOD_bsp_left(node) && !TCOD_bsp_traverse_in_order(TCOD_bsp_left(node),listener,userData)) return false; if (!listener(node,userData)) return false; if ( TCOD_bsp_right(node) && !TCOD_bsp_traverse_in_order(TCOD_bsp_right(node),listener,userData)) return false; return true; } bool TCOD_bsp_traverse_post_order(TCOD_bsp_t *node, TCOD_bsp_callback_t listener, void *userData) { if ( TCOD_bsp_left(node) && !TCOD_bsp_traverse_post_order(TCOD_bsp_left(node),listener,userData)) return false; if ( TCOD_bsp_right(node) && !TCOD_bsp_traverse_post_order(TCOD_bsp_right(node),listener,userData)) return false; if (!listener(node,userData)) return false; return true; } bool TCOD_bsp_traverse_level_order(TCOD_bsp_t *node, TCOD_bsp_callback_t listener, void *userData) { TCOD_list_t stack=TCOD_list_new(); TCOD_list_push(stack,node); while ( ! TCOD_list_is_empty(stack) ) { TCOD_bsp_t *node=(TCOD_bsp_t *)TCOD_list_get(stack,0); TCOD_list_remove(stack,node); if ( TCOD_bsp_left(node) ) TCOD_list_push(stack,TCOD_bsp_left(node)); if ( TCOD_bsp_right(node) ) TCOD_list_push(stack,TCOD_bsp_right(node)); if (!listener(node,userData)) { TCOD_list_delete(stack); return false; } } TCOD_list_delete(stack); return true; } bool TCOD_bsp_traverse_inverted_level_order(TCOD_bsp_t *node, TCOD_bsp_callback_t listener, void *userData) { TCOD_list_t stack1=TCOD_list_new(); TCOD_list_t stack2=TCOD_list_new(); TCOD_list_push(stack1,node); while ( ! TCOD_list_is_empty(stack1) ) { TCOD_bsp_t *node=(TCOD_bsp_t *)TCOD_list_get(stack1,0); TCOD_list_push(stack2,node); TCOD_list_remove(stack1,node); if ( TCOD_bsp_left(node) ) TCOD_list_push(stack1,TCOD_bsp_left(node)); if ( TCOD_bsp_right(node) ) TCOD_list_push(stack1,TCOD_bsp_right(node)); } while ( ! TCOD_list_is_empty(stack2) ) { TCOD_bsp_t *node=(TCOD_bsp_t *)TCOD_list_pop(stack2); if (!listener(node,userData)) { TCOD_list_delete(stack1); TCOD_list_delete(stack2); return false; } } TCOD_list_delete(stack1); TCOD_list_delete(stack2); return true; } void TCOD_bsp_remove_sons(TCOD_bsp_t *root) { TCOD_bsp_t *node=(TCOD_bsp_t *)root->tree.sons; while ( node ) { TCOD_bsp_t *nextNode=(TCOD_bsp_t *)node->tree.next; TCOD_bsp_remove_sons(node); free( node ); node=nextNode; } root->tree.sons=NULL; } void TCOD_bsp_split_once(TCOD_bsp_t *node, bool horizontal, int position) { node->horizontal = horizontal; node->position=position; TCOD_tree_add_son(&node->tree,&TCOD_bsp_new_intern(node,true)->tree); TCOD_tree_add_son(&node->tree,&TCOD_bsp_new_intern(node,false)->tree); } void TCOD_bsp_split_recursive(TCOD_bsp_t *node, TCOD_random_t randomizer, int nb, int minHSize, int minVSize, float maxHRatio, float maxVRatio) { bool horiz; int position; if ( nb == 0 || (node->w < 2*minHSize && node->h < 2*minVSize ) ) return; if (! randomizer ) randomizer=TCOD_random_get_instance(); /* promote square rooms */ if ( node->h < 2*minVSize || node->w > node->h * maxHRatio ) horiz = false; else if ( node->w < 2*minHSize || node->h > node->w * maxVRatio) horiz = true; else horiz = (TCOD_random_get_int(randomizer,0,1) == 0); if ( horiz ) { position = TCOD_random_get_int(randomizer,node->y+minVSize,node->y+node->h-minVSize); } else { position = TCOD_random_get_int(randomizer,node->x+minHSize,node->x+node->w-minHSize); } TCOD_bsp_split_once(node,horiz,position); TCOD_bsp_split_recursive(TCOD_bsp_left(node),randomizer,nb-1,minHSize,minVSize,maxHRatio,maxVRatio); TCOD_bsp_split_recursive(TCOD_bsp_right(node),randomizer,nb-1,minHSize,minVSize,maxHRatio,maxVRatio); } void TCOD_bsp_resize(TCOD_bsp_t *node, int x,int y, int w, int h) { node->x=x; node->y=y; node->w=w; node->h=h; if ( TCOD_bsp_left(node) ) { if ( node->horizontal ) { TCOD_bsp_resize(TCOD_bsp_left(node),x,y,w,node->position-y); TCOD_bsp_resize(TCOD_bsp_right(node),x,node->position,w,y+h-node->position); } else { TCOD_bsp_resize(TCOD_bsp_left(node),x,y,node->position-x,h); TCOD_bsp_resize(TCOD_bsp_right(node),node->position,y,x+w-node->position,h); } } } bool TCOD_bsp_contains(TCOD_bsp_t *node, int x, int y) { return (x >= node->x && y >= node->y && x < node->x+node->w && y < node->y+node->h); } TCOD_bsp_t * TCOD_bsp_find_node(TCOD_bsp_t *node, int x, int y) { if ( ! TCOD_bsp_contains(node,x,y) ) return NULL; if ( ! TCOD_bsp_is_leaf(node) ) { TCOD_bsp_t *left,*right; left=TCOD_bsp_left(node); if ( TCOD_bsp_contains(left,x,y) ) return TCOD_bsp_find_node(left,x,y); right=TCOD_bsp_right(node); if ( TCOD_bsp_contains(right,x,y) ) return TCOD_bsp_find_node(right,x,y); } return node; } libtcod-1.6.4+dfsg/src/color.cpp000066400000000000000000000467601321276576200165220ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include // grey levels const TCODColor TCODColor::black(TCOD_BLACK); const TCODColor TCODColor::darkestGrey(TCOD_DARKEST_GREY); const TCODColor TCODColor::darkerGrey(TCOD_DARKER_GREY); const TCODColor TCODColor::darkGrey(TCOD_DARK_GREY); const TCODColor TCODColor::grey(TCOD_GREY); const TCODColor TCODColor::lightGrey(TCOD_LIGHT_GREY); const TCODColor TCODColor::lighterGrey(TCOD_LIGHTER_GREY); const TCODColor TCODColor::lightestGrey(TCOD_LIGHTEST_GREY); const TCODColor TCODColor::white(TCOD_WHITE); //sepia const TCODColor TCODColor::darkestSepia(TCOD_DARKEST_SEPIA); const TCODColor TCODColor::darkerSepia(TCOD_DARKER_SEPIA); const TCODColor TCODColor::darkSepia(TCOD_DARK_SEPIA); const TCODColor TCODColor::sepia(TCOD_SEPIA); const TCODColor TCODColor::lightSepia(TCOD_LIGHT_SEPIA); const TCODColor TCODColor::lighterSepia(TCOD_LIGHTER_SEPIA); const TCODColor TCODColor::lightestSepia(TCOD_LIGHTEST_SEPIA); // standard colors const TCODColor TCODColor::red(TCOD_RED); const TCODColor TCODColor::flame(TCOD_FLAME); const TCODColor TCODColor::orange(TCOD_ORANGE); const TCODColor TCODColor::amber(TCOD_AMBER); const TCODColor TCODColor::yellow(TCOD_YELLOW); const TCODColor TCODColor::lime(TCOD_LIME); const TCODColor TCODColor::chartreuse(TCOD_CHARTREUSE); const TCODColor TCODColor::green(TCOD_GREEN); const TCODColor TCODColor::sea(TCOD_SEA); const TCODColor TCODColor::turquoise(TCOD_TURQUOISE); const TCODColor TCODColor::cyan(TCOD_CYAN); const TCODColor TCODColor::sky(TCOD_SKY); const TCODColor TCODColor::azure(TCOD_AZURE); const TCODColor TCODColor::blue(TCOD_BLUE); const TCODColor TCODColor::han(TCOD_HAN); const TCODColor TCODColor::violet(TCOD_VIOLET); const TCODColor TCODColor::purple(TCOD_PURPLE); const TCODColor TCODColor::fuchsia(TCOD_FUCHSIA); const TCODColor TCODColor::magenta(TCOD_MAGENTA); const TCODColor TCODColor::pink(TCOD_PINK); const TCODColor TCODColor::crimson(TCOD_CRIMSON); // dark colors const TCODColor TCODColor::darkRed(TCOD_DARK_RED); const TCODColor TCODColor::darkFlame(TCOD_DARK_FLAME); const TCODColor TCODColor::darkOrange(TCOD_DARK_ORANGE); const TCODColor TCODColor::darkAmber(TCOD_DARK_AMBER); const TCODColor TCODColor::darkYellow(TCOD_DARK_YELLOW); const TCODColor TCODColor::darkLime(TCOD_DARK_LIME); const TCODColor TCODColor::darkChartreuse(TCOD_DARK_CHARTREUSE); const TCODColor TCODColor::darkGreen(TCOD_DARK_GREEN); const TCODColor TCODColor::darkSea(TCOD_DARK_SEA); const TCODColor TCODColor::darkTurquoise(TCOD_DARK_TURQUOISE); const TCODColor TCODColor::darkCyan(TCOD_DARK_CYAN); const TCODColor TCODColor::darkSky(TCOD_DARK_SKY); const TCODColor TCODColor::darkAzure(TCOD_DARK_AZURE); const TCODColor TCODColor::darkBlue(TCOD_DARK_BLUE); const TCODColor TCODColor::darkHan(TCOD_DARK_HAN); const TCODColor TCODColor::darkViolet(TCOD_DARK_VIOLET); const TCODColor TCODColor::darkPurple(TCOD_DARK_PURPLE); const TCODColor TCODColor::darkFuchsia(TCOD_DARK_FUCHSIA); const TCODColor TCODColor::darkMagenta(TCOD_DARK_MAGENTA); const TCODColor TCODColor::darkPink(TCOD_DARK_PINK); const TCODColor TCODColor::darkCrimson(TCOD_DARK_CRIMSON); // darker colors const TCODColor TCODColor::darkerRed(TCOD_DARKER_RED); const TCODColor TCODColor::darkerFlame(TCOD_DARKER_FLAME); const TCODColor TCODColor::darkerOrange(TCOD_DARKER_ORANGE); const TCODColor TCODColor::darkerAmber(TCOD_DARKER_AMBER); const TCODColor TCODColor::darkerYellow(TCOD_DARKER_YELLOW); const TCODColor TCODColor::darkerLime(TCOD_DARKER_LIME); const TCODColor TCODColor::darkerChartreuse(TCOD_DARKER_CHARTREUSE); const TCODColor TCODColor::darkerGreen(TCOD_DARKER_GREEN); const TCODColor TCODColor::darkerSea(TCOD_DARKER_SEA); const TCODColor TCODColor::darkerTurquoise(TCOD_DARKER_TURQUOISE); const TCODColor TCODColor::darkerCyan(TCOD_DARKER_CYAN); const TCODColor TCODColor::darkerSky(TCOD_DARKER_SKY); const TCODColor TCODColor::darkerAzure(TCOD_DARKER_AZURE); const TCODColor TCODColor::darkerBlue(TCOD_DARKER_BLUE); const TCODColor TCODColor::darkerHan(TCOD_DARKER_HAN); const TCODColor TCODColor::darkerViolet(TCOD_DARKER_VIOLET); const TCODColor TCODColor::darkerPurple(TCOD_DARKER_PURPLE); const TCODColor TCODColor::darkerFuchsia(TCOD_DARKER_FUCHSIA); const TCODColor TCODColor::darkerMagenta(TCOD_DARKER_MAGENTA); const TCODColor TCODColor::darkerPink(TCOD_DARKER_PINK); const TCODColor TCODColor::darkerCrimson(TCOD_DARKER_CRIMSON); // darkest colors const TCODColor TCODColor::darkestRed(TCOD_DARKEST_RED); const TCODColor TCODColor::darkestFlame(TCOD_DARKEST_FLAME); const TCODColor TCODColor::darkestOrange(TCOD_DARKEST_ORANGE); const TCODColor TCODColor::darkestAmber(TCOD_DARKEST_AMBER); const TCODColor TCODColor::darkestYellow(TCOD_DARKEST_YELLOW); const TCODColor TCODColor::darkestLime(TCOD_DARKEST_LIME); const TCODColor TCODColor::darkestChartreuse(TCOD_DARKEST_CHARTREUSE); const TCODColor TCODColor::darkestGreen(TCOD_DARKEST_GREEN); const TCODColor TCODColor::darkestSea(TCOD_DARKEST_SEA); const TCODColor TCODColor::darkestTurquoise(TCOD_DARKEST_TURQUOISE); const TCODColor TCODColor::darkestCyan(TCOD_DARKEST_CYAN); const TCODColor TCODColor::darkestSky(TCOD_DARKEST_SKY); const TCODColor TCODColor::darkestAzure(TCOD_DARKEST_AZURE); const TCODColor TCODColor::darkestBlue(TCOD_DARKEST_BLUE); const TCODColor TCODColor::darkestHan(TCOD_DARKEST_HAN); const TCODColor TCODColor::darkestViolet(TCOD_DARKEST_VIOLET); const TCODColor TCODColor::darkestPurple(TCOD_DARKEST_PURPLE); const TCODColor TCODColor::darkestFuchsia(TCOD_DARKEST_FUCHSIA); const TCODColor TCODColor::darkestMagenta(TCOD_DARKEST_MAGENTA); const TCODColor TCODColor::darkestPink(TCOD_DARKEST_PINK); const TCODColor TCODColor::darkestCrimson(TCOD_DARKEST_CRIMSON); // light colors const TCODColor TCODColor::lightRed(TCOD_LIGHT_RED); const TCODColor TCODColor::lightFlame(TCOD_LIGHT_FLAME); const TCODColor TCODColor::lightOrange(TCOD_LIGHT_ORANGE); const TCODColor TCODColor::lightAmber(TCOD_LIGHT_AMBER); const TCODColor TCODColor::lightYellow(TCOD_LIGHT_YELLOW); const TCODColor TCODColor::lightLime(TCOD_LIGHT_LIME); const TCODColor TCODColor::lightChartreuse(TCOD_LIGHT_CHARTREUSE); const TCODColor TCODColor::lightGreen(TCOD_LIGHT_GREEN); const TCODColor TCODColor::lightSea(TCOD_LIGHT_SEA); const TCODColor TCODColor::lightTurquoise(TCOD_LIGHT_TURQUOISE); const TCODColor TCODColor::lightCyan(TCOD_LIGHT_CYAN); const TCODColor TCODColor::lightSky(TCOD_LIGHT_SKY); const TCODColor TCODColor::lightAzure(TCOD_LIGHT_AZURE); const TCODColor TCODColor::lightBlue(TCOD_LIGHT_BLUE); const TCODColor TCODColor::lightHan(TCOD_LIGHT_HAN); const TCODColor TCODColor::lightViolet(TCOD_LIGHT_VIOLET); const TCODColor TCODColor::lightPurple(TCOD_LIGHT_PURPLE); const TCODColor TCODColor::lightFuchsia(TCOD_LIGHT_FUCHSIA); const TCODColor TCODColor::lightMagenta(TCOD_LIGHT_MAGENTA); const TCODColor TCODColor::lightPink(TCOD_LIGHT_PINK); const TCODColor TCODColor::lightCrimson(TCOD_LIGHT_CRIMSON); // lighter colors const TCODColor TCODColor::lighterRed(TCOD_LIGHTER_RED); const TCODColor TCODColor::lighterFlame(TCOD_LIGHTER_FLAME); const TCODColor TCODColor::lighterOrange(TCOD_LIGHTER_ORANGE); const TCODColor TCODColor::lighterAmber(TCOD_LIGHTER_AMBER); const TCODColor TCODColor::lighterYellow(TCOD_LIGHTER_YELLOW); const TCODColor TCODColor::lighterLime(TCOD_LIGHTER_LIME); const TCODColor TCODColor::lighterChartreuse(TCOD_LIGHTER_CHARTREUSE); const TCODColor TCODColor::lighterGreen(TCOD_LIGHTER_GREEN); const TCODColor TCODColor::lighterSea(TCOD_LIGHTER_SEA); const TCODColor TCODColor::lighterTurquoise(TCOD_LIGHTER_TURQUOISE); const TCODColor TCODColor::lighterCyan(TCOD_LIGHTER_CYAN); const TCODColor TCODColor::lighterSky(TCOD_LIGHTER_SKY); const TCODColor TCODColor::lighterAzure(TCOD_LIGHTER_AZURE); const TCODColor TCODColor::lighterBlue(TCOD_LIGHTER_BLUE); const TCODColor TCODColor::lighterHan(TCOD_LIGHTER_HAN); const TCODColor TCODColor::lighterViolet(TCOD_LIGHTER_VIOLET); const TCODColor TCODColor::lighterPurple(TCOD_LIGHTER_PURPLE); const TCODColor TCODColor::lighterFuchsia(TCOD_LIGHTER_FUCHSIA); const TCODColor TCODColor::lighterMagenta(TCOD_LIGHTER_MAGENTA); const TCODColor TCODColor::lighterPink(TCOD_LIGHTER_PINK); const TCODColor TCODColor::lighterCrimson(TCOD_LIGHTER_CRIMSON); // lightest colors const TCODColor TCODColor::lightestRed(TCOD_LIGHTEST_RED); const TCODColor TCODColor::lightestFlame(TCOD_LIGHTEST_FLAME); const TCODColor TCODColor::lightestOrange(TCOD_LIGHTEST_ORANGE); const TCODColor TCODColor::lightestAmber(TCOD_LIGHTEST_AMBER); const TCODColor TCODColor::lightestYellow(TCOD_LIGHTEST_YELLOW); const TCODColor TCODColor::lightestLime(TCOD_LIGHTEST_LIME); const TCODColor TCODColor::lightestChartreuse(TCOD_LIGHTEST_CHARTREUSE); const TCODColor TCODColor::lightestGreen(TCOD_LIGHTEST_GREEN); const TCODColor TCODColor::lightestSea(TCOD_LIGHTEST_SEA); const TCODColor TCODColor::lightestTurquoise(TCOD_LIGHTEST_TURQUOISE); const TCODColor TCODColor::lightestCyan(TCOD_LIGHTEST_CYAN); const TCODColor TCODColor::lightestSky(TCOD_LIGHTEST_SKY); const TCODColor TCODColor::lightestAzure(TCOD_LIGHTEST_AZURE); const TCODColor TCODColor::lightestBlue(TCOD_LIGHTEST_BLUE); const TCODColor TCODColor::lightestHan(TCOD_LIGHTEST_HAN); const TCODColor TCODColor::lightestViolet(TCOD_LIGHTEST_VIOLET); const TCODColor TCODColor::lightestPurple(TCOD_LIGHTEST_PURPLE); const TCODColor TCODColor::lightestFuchsia(TCOD_LIGHTEST_FUCHSIA); const TCODColor TCODColor::lightestMagenta(TCOD_LIGHTEST_MAGENTA); const TCODColor TCODColor::lightestPink(TCOD_LIGHTEST_PINK); const TCODColor TCODColor::lightestCrimson(TCOD_LIGHTEST_CRIMSON); // desaturated colors const TCODColor TCODColor::desaturatedRed(TCOD_DESATURATED_RED); const TCODColor TCODColor::desaturatedFlame(TCOD_DESATURATED_FLAME); const TCODColor TCODColor::desaturatedOrange(TCOD_DESATURATED_ORANGE); const TCODColor TCODColor::desaturatedAmber(TCOD_DESATURATED_AMBER); const TCODColor TCODColor::desaturatedYellow(TCOD_DESATURATED_YELLOW); const TCODColor TCODColor::desaturatedLime(TCOD_DESATURATED_LIME); const TCODColor TCODColor::desaturatedChartreuse(TCOD_DESATURATED_CHARTREUSE); const TCODColor TCODColor::desaturatedGreen(TCOD_DESATURATED_GREEN); const TCODColor TCODColor::desaturatedSea(TCOD_DESATURATED_SEA); const TCODColor TCODColor::desaturatedTurquoise(TCOD_DESATURATED_TURQUOISE); const TCODColor TCODColor::desaturatedCyan(TCOD_DESATURATED_CYAN); const TCODColor TCODColor::desaturatedSky(TCOD_DESATURATED_SKY); const TCODColor TCODColor::desaturatedAzure(TCOD_DESATURATED_AZURE); const TCODColor TCODColor::desaturatedBlue(TCOD_DESATURATED_BLUE); const TCODColor TCODColor::desaturatedHan(TCOD_DESATURATED_HAN); const TCODColor TCODColor::desaturatedViolet(TCOD_DESATURATED_VIOLET); const TCODColor TCODColor::desaturatedPurple(TCOD_DESATURATED_PURPLE); const TCODColor TCODColor::desaturatedFuchsia(TCOD_DESATURATED_FUCHSIA); const TCODColor TCODColor::desaturatedMagenta(TCOD_DESATURATED_MAGENTA); const TCODColor TCODColor::desaturatedPink(TCOD_DESATURATED_PINK); const TCODColor TCODColor::desaturatedCrimson(TCOD_DESATURATED_CRIMSON); //special const TCODColor TCODColor::brass(TCOD_BRASS); const TCODColor TCODColor::copper(TCOD_COPPER); const TCODColor TCODColor::gold(TCOD_GOLD); const TCODColor TCODColor::silver(TCOD_SILVER); //miscellaneous const TCODColor TCODColor::celadon(TCOD_CELADON); const TCODColor TCODColor::peach(TCOD_PEACH); #ifndef TCOD_HAIKU // color array const TCODColor TCODColor::colors[TCOD_COLOR_NB][TCOD_COLOR_LEVELS] = { {TCODColor(TCOD_DESATURATED_RED),TCODColor(TCOD_LIGHTEST_RED),TCODColor(TCOD_LIGHTER_RED),TCODColor(TCOD_LIGHT_RED),TCODColor(TCOD_RED),TCODColor(TCOD_DARK_RED),TCODColor(TCOD_DARKER_RED),TCODColor(TCOD_DARKEST_RED)}, {TCODColor(TCOD_DESATURATED_FLAME),TCODColor(TCOD_LIGHTEST_FLAME),TCODColor(TCOD_LIGHTER_FLAME),TCODColor(TCOD_LIGHT_FLAME),TCODColor(TCOD_FLAME),TCODColor(TCOD_DARK_FLAME),TCODColor(TCOD_DARKER_FLAME),TCODColor(TCOD_DARKEST_FLAME)}, {TCODColor(TCOD_DESATURATED_ORANGE),TCODColor(TCOD_LIGHTEST_ORANGE),TCODColor(TCOD_LIGHTER_ORANGE),TCODColor(TCOD_LIGHT_ORANGE),TCODColor(TCOD_ORANGE),TCODColor(TCOD_DARK_ORANGE),TCODColor(TCOD_DARKER_ORANGE),TCODColor(TCOD_DARKEST_ORANGE)}, {TCODColor(TCOD_DESATURATED_AMBER),TCODColor(TCOD_LIGHTEST_AMBER),TCODColor(TCOD_LIGHTER_AMBER),TCODColor(TCOD_LIGHT_AMBER),TCODColor(TCOD_AMBER),TCODColor(TCOD_DARK_AMBER),TCODColor(TCOD_DARKER_AMBER),TCODColor(TCOD_DARKEST_AMBER)}, {TCODColor(TCOD_DESATURATED_YELLOW),TCODColor(TCOD_LIGHTEST_YELLOW),TCODColor(TCOD_LIGHTER_YELLOW),TCODColor(TCOD_LIGHT_YELLOW),TCODColor(TCOD_YELLOW),TCODColor(TCOD_DARK_YELLOW),TCODColor(TCOD_DARKER_YELLOW),TCODColor(TCOD_DARKEST_YELLOW)}, {TCODColor(TCOD_DESATURATED_LIME),TCODColor(TCOD_LIGHTEST_LIME),TCODColor(TCOD_LIGHTER_LIME),TCODColor(TCOD_LIGHT_LIME),TCODColor(TCOD_LIME),TCODColor(TCOD_DARK_LIME),TCODColor(TCOD_DARKER_LIME),TCODColor(TCOD_DARKEST_LIME)}, {TCODColor(TCOD_DESATURATED_CHARTREUSE),TCODColor(TCOD_LIGHTEST_CHARTREUSE),TCODColor(TCOD_LIGHTER_CHARTREUSE),TCODColor(TCOD_LIGHT_CHARTREUSE),TCODColor(TCOD_CHARTREUSE),TCODColor(TCOD_DARK_CHARTREUSE),TCODColor(TCOD_DARKER_CHARTREUSE),TCODColor(TCOD_DARKEST_CHARTREUSE)}, {TCODColor(TCOD_DESATURATED_GREEN),TCODColor(TCOD_LIGHTEST_GREEN),TCODColor(TCOD_LIGHTER_GREEN),TCODColor(TCOD_LIGHT_GREEN),TCODColor(TCOD_GREEN),TCODColor(TCOD_DARK_GREEN),TCODColor(TCOD_DARKER_GREEN),TCODColor(TCOD_DARKEST_GREEN)}, {TCODColor(TCOD_DESATURATED_SEA),TCODColor(TCOD_LIGHTEST_SEA),TCODColor(TCOD_LIGHTER_SEA),TCODColor(TCOD_LIGHT_SEA),TCODColor(TCOD_SEA),TCODColor(TCOD_DARK_SEA),TCODColor(TCOD_DARKER_SEA),TCODColor(TCOD_DARKEST_SEA)}, {TCODColor(TCOD_DESATURATED_TURQUOISE),TCODColor(TCOD_LIGHTEST_TURQUOISE),TCODColor(TCOD_LIGHTER_TURQUOISE),TCODColor(TCOD_LIGHT_TURQUOISE),TCODColor(TCOD_TURQUOISE),TCODColor(TCOD_DARK_TURQUOISE),TCODColor(TCOD_DARKER_TURQUOISE),TCODColor(TCOD_DARKEST_TURQUOISE)}, {TCODColor(TCOD_DESATURATED_CYAN),TCODColor(TCOD_LIGHTEST_CYAN),TCODColor(TCOD_LIGHTER_CYAN),TCODColor(TCOD_LIGHT_CYAN),TCODColor(TCOD_CYAN),TCODColor(TCOD_DARK_CYAN),TCODColor(TCOD_DARKER_CYAN),TCODColor(TCOD_DARKEST_CYAN)}, {TCODColor(TCOD_DESATURATED_SKY),TCODColor(TCOD_LIGHTEST_SKY),TCODColor(TCOD_LIGHTER_SKY),TCODColor(TCOD_LIGHT_SKY),TCODColor(TCOD_SKY),TCODColor(TCOD_DARK_SKY),TCODColor(TCOD_DARKER_SKY),TCODColor(TCOD_DARKEST_SKY)}, {TCODColor(TCOD_DESATURATED_AZURE),TCODColor(TCOD_LIGHTEST_AZURE),TCODColor(TCOD_LIGHTER_AZURE),TCODColor(TCOD_LIGHT_AZURE),TCODColor(TCOD_AZURE),TCODColor(TCOD_DARK_AZURE),TCODColor(TCOD_DARKER_AZURE),TCODColor(TCOD_DARKEST_AZURE)}, {TCODColor(TCOD_DESATURATED_BLUE),TCODColor(TCOD_LIGHTEST_BLUE),TCODColor(TCOD_LIGHTER_BLUE),TCODColor(TCOD_LIGHT_BLUE),TCODColor(TCOD_BLUE),TCODColor(TCOD_DARK_BLUE),TCODColor(TCOD_DARKER_BLUE),TCODColor(TCOD_DARKEST_BLUE)}, {TCODColor(TCOD_DESATURATED_HAN),TCODColor(TCOD_LIGHTEST_HAN),TCODColor(TCOD_LIGHTER_HAN),TCODColor(TCOD_LIGHT_HAN),TCODColor(TCOD_HAN),TCODColor(TCOD_DARK_HAN),TCODColor(TCOD_DARKER_HAN),TCODColor(TCOD_DARKEST_HAN)}, {TCODColor(TCOD_DESATURATED_VIOLET),TCODColor(TCOD_LIGHTEST_VIOLET),TCODColor(TCOD_LIGHTER_VIOLET),TCODColor(TCOD_LIGHT_VIOLET),TCODColor(TCOD_VIOLET),TCODColor(TCOD_DARK_VIOLET),TCODColor(TCOD_DARKER_VIOLET),TCODColor(TCOD_DARKEST_VIOLET)}, {TCODColor(TCOD_DESATURATED_PURPLE),TCODColor(TCOD_LIGHTEST_PURPLE),TCODColor(TCOD_LIGHTER_PURPLE),TCODColor(TCOD_LIGHT_PURPLE),TCODColor(TCOD_PURPLE),TCODColor(TCOD_DARK_PURPLE),TCODColor(TCOD_DARKER_PURPLE),TCODColor(TCOD_DARKEST_PURPLE)}, {TCODColor(TCOD_DESATURATED_FUCHSIA),TCODColor(TCOD_LIGHTEST_FUCHSIA),TCODColor(TCOD_LIGHTER_FUCHSIA),TCODColor(TCOD_LIGHT_FUCHSIA),TCODColor(TCOD_FUCHSIA),TCODColor(TCOD_DARK_FUCHSIA),TCODColor(TCOD_DARKER_FUCHSIA),TCODColor(TCOD_DARKEST_FUCHSIA)}, {TCODColor(TCOD_DESATURATED_MAGENTA),TCODColor(TCOD_LIGHTEST_MAGENTA),TCODColor(TCOD_LIGHTER_MAGENTA),TCODColor(TCOD_LIGHT_MAGENTA),TCODColor(TCOD_MAGENTA),TCODColor(TCOD_DARK_MAGENTA),TCODColor(TCOD_DARKER_MAGENTA),TCODColor(TCOD_DARKEST_MAGENTA)}, {TCODColor(TCOD_DESATURATED_PINK),TCODColor(TCOD_LIGHTEST_PINK),TCODColor(TCOD_LIGHTER_PINK),TCODColor(TCOD_LIGHT_PINK),TCODColor(TCOD_PINK),TCODColor(TCOD_DARK_PINK),TCODColor(TCOD_DARKER_PINK),TCODColor(TCOD_DARKEST_PINK)}, {TCODColor(TCOD_DESATURATED_CRIMSON),TCODColor(TCOD_LIGHTEST_CRIMSON),TCODColor(TCOD_LIGHTER_CRIMSON),TCODColor(TCOD_LIGHT_CRIMSON),TCODColor(TCOD_CRIMSON),TCODColor(TCOD_DARK_CRIMSON),TCODColor(TCOD_DARKER_CRIMSON),TCODColor(TCOD_DARKEST_CRIMSON)} }; #endif TCODColor::TCODColor(float h, float s, float v) { //setHSV(h,s,v); TCOD_color_t c = TCOD_color_HSV(h,s,v); r = c.r; g = c.g; b = c.b; } void TCODColor::setHSV(float h, float s, float v) { TCOD_color_t c; TCOD_color_set_HSV(&c,h,s,v); r = c.r; g = c.g; b = c.b; } void TCODColor::setHue (float h) { TCOD_color_t c = { r, g, b }; TCOD_color_set_hue (&c, h); r = c.r; g = c.g; b = c.b; } void TCODColor::setSaturation (float s) { TCOD_color_t c = { r, g, b }; TCOD_color_set_saturation (&c, s); r = c.r; g = c.g; b = c.b; } void TCODColor::setValue (float v) { TCOD_color_t c = { r, g, b }; TCOD_color_set_value (&c, v); r = c.r; g = c.g; b = c.b; } void TCODColor::getHSV(float *h, float *s, float *v) const { TCOD_color_t c={r,g,b}; TCOD_color_get_HSV(c,h,s,v); } float TCODColor::getHue () { TCOD_color_t c = { r, g, b }; return TCOD_color_get_hue(c); } float TCODColor::getSaturation () { TCOD_color_t c = { r, g, b }; return TCOD_color_get_saturation(c); } float TCODColor::getValue () { TCOD_color_t c = { r, g, b }; return TCOD_color_get_value(c); } void TCODColor::shiftHue (float hshift) { TCOD_color_t c = { r, g, b }; TCOD_color_shift_hue (&c, hshift); r = c.r; g = c.g; b = c.b; } void TCODColor::scaleHSV (float sscale, float vscale) { TCOD_color_t c = {r,g,b}; TCOD_color_scale_HSV(&c,sscale,vscale); r = c.r; g = c.g; b = c.b; } // non member operators TCODColor operator *(float value, const TCODColor &c) { return c*value; } void TCODColor::genMap(TCODColor *map, int nbKey, TCODColor const *keyColor, int const *keyIndex) { for (int segment=0; segment < nbKey-1; segment++) { int idxStart=keyIndex[segment]; int idxEnd=keyIndex[segment+1]; int idx; for ( idx=idxStart;idx <= idxEnd; idx++) { map[idx]=TCODColor::lerp(keyColor[segment],keyColor[segment+1],(float)(idx-idxStart)/(idxEnd-idxStart)); } } } libtcod-1.6.4+dfsg/src/color_c.c000066400000000000000000000573121321276576200164570ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include /* grey levels */ const TCOD_color_t TCOD_black={TCOD_BLACK}; const TCOD_color_t TCOD_darkest_grey={TCOD_DARKEST_GREY}; const TCOD_color_t TCOD_darker_grey={TCOD_DARKER_GREY}; const TCOD_color_t TCOD_dark_grey={TCOD_DARK_GREY}; const TCOD_color_t TCOD_grey={TCOD_GREY}; const TCOD_color_t TCOD_light_grey={TCOD_LIGHT_GREY}; const TCOD_color_t TCOD_lighter_grey={TCOD_LIGHTER_GREY}; const TCOD_color_t TCOD_lightest_grey={TCOD_LIGHTEST_GREY}; const TCOD_color_t TCOD_darkest_gray={TCOD_DARKEST_GREY}; const TCOD_color_t TCOD_darker_gray={TCOD_DARKER_GREY}; const TCOD_color_t TCOD_dark_gray={TCOD_DARK_GREY}; const TCOD_color_t TCOD_gray={TCOD_GREY}; const TCOD_color_t TCOD_light_gray={TCOD_LIGHT_GREY}; const TCOD_color_t TCOD_lighter_gray={TCOD_LIGHTER_GREY}; const TCOD_color_t TCOD_lightest_gray={TCOD_LIGHTEST_GREY}; const TCOD_color_t TCOD_white={TCOD_WHITE}; /* sepia */ const TCOD_color_t TCOD_darkest_sepia={TCOD_DARKEST_SEPIA}; const TCOD_color_t TCOD_darker_sepia={TCOD_DARKER_SEPIA}; const TCOD_color_t TCOD_dark_sepia={TCOD_DARK_SEPIA}; const TCOD_color_t TCOD_sepia={TCOD_SEPIA}; const TCOD_color_t TCOD_light_sepia={TCOD_LIGHT_SEPIA}; const TCOD_color_t TCOD_lighter_sepia={TCOD_LIGHTER_SEPIA}; const TCOD_color_t TCOD_lightest_sepia={TCOD_LIGHTEST_SEPIA}; /* standard colors */ const TCOD_color_t TCOD_red = {TCOD_RED}; const TCOD_color_t TCOD_flame = {TCOD_FLAME}; const TCOD_color_t TCOD_orange = {TCOD_ORANGE}; const TCOD_color_t TCOD_amber = {TCOD_AMBER}; const TCOD_color_t TCOD_yellow = {TCOD_YELLOW}; const TCOD_color_t TCOD_lime = {TCOD_LIME}; const TCOD_color_t TCOD_chartreuse = {TCOD_CHARTREUSE}; const TCOD_color_t TCOD_green = {TCOD_GREEN}; const TCOD_color_t TCOD_sea = {TCOD_SEA}; const TCOD_color_t TCOD_turquoise = {TCOD_TURQUOISE}; const TCOD_color_t TCOD_cyan = {TCOD_CYAN}; const TCOD_color_t TCOD_sky = {TCOD_SKY}; const TCOD_color_t TCOD_azure = {TCOD_AZURE}; const TCOD_color_t TCOD_blue = {TCOD_BLUE}; const TCOD_color_t TCOD_han = {TCOD_HAN}; const TCOD_color_t TCOD_violet = {TCOD_VIOLET}; const TCOD_color_t TCOD_purple = {TCOD_PURPLE}; const TCOD_color_t TCOD_fuchsia = {TCOD_FUCHSIA}; const TCOD_color_t TCOD_magenta = {TCOD_MAGENTA}; const TCOD_color_t TCOD_pink = {TCOD_PINK}; const TCOD_color_t TCOD_crimson = {TCOD_CRIMSON}; /* dark colors */ const TCOD_color_t TCOD_dark_red = {TCOD_DARK_RED}; const TCOD_color_t TCOD_dark_flame = {TCOD_DARK_FLAME}; const TCOD_color_t TCOD_dark_orange = {TCOD_DARK_ORANGE}; const TCOD_color_t TCOD_dark_amber = {TCOD_DARK_AMBER}; const TCOD_color_t TCOD_dark_yellow = {TCOD_DARK_YELLOW}; const TCOD_color_t TCOD_dark_lime = {TCOD_DARK_LIME}; const TCOD_color_t TCOD_dark_chartreuse = {TCOD_DARK_CHARTREUSE}; const TCOD_color_t TCOD_dark_green = {TCOD_DARK_GREEN}; const TCOD_color_t TCOD_dark_sea = {TCOD_DARK_SEA}; const TCOD_color_t TCOD_dark_turquoise = {TCOD_DARK_TURQUOISE}; const TCOD_color_t TCOD_dark_cyan = {TCOD_DARK_CYAN}; const TCOD_color_t TCOD_dark_sky = {TCOD_DARK_SKY}; const TCOD_color_t TCOD_dark_azure = {TCOD_DARK_AZURE}; const TCOD_color_t TCOD_dark_blue = {TCOD_DARK_BLUE}; const TCOD_color_t TCOD_dark_han = {TCOD_DARK_HAN}; const TCOD_color_t TCOD_dark_violet = {TCOD_DARK_VIOLET}; const TCOD_color_t TCOD_dark_purple = {TCOD_DARK_PURPLE}; const TCOD_color_t TCOD_dark_fuchsia = {TCOD_DARK_FUCHSIA}; const TCOD_color_t TCOD_dark_magenta = {TCOD_DARK_MAGENTA}; const TCOD_color_t TCOD_dark_pink = {TCOD_DARK_PINK}; const TCOD_color_t TCOD_dark_crimson = {TCOD_DARK_CRIMSON}; /* darker colors */ const TCOD_color_t TCOD_darker_red = {TCOD_DARKER_RED}; const TCOD_color_t TCOD_darker_flame = {TCOD_DARKER_FLAME}; const TCOD_color_t TCOD_darker_orange = {TCOD_DARKER_ORANGE}; const TCOD_color_t TCOD_darker_amber = {TCOD_DARKER_AMBER}; const TCOD_color_t TCOD_darker_yellow = {TCOD_DARKER_YELLOW}; const TCOD_color_t TCOD_darker_lime = {TCOD_DARKER_LIME}; const TCOD_color_t TCOD_darker_chartreuse = {TCOD_DARKER_CHARTREUSE}; const TCOD_color_t TCOD_darker_green = {TCOD_DARKER_GREEN}; const TCOD_color_t TCOD_darker_sea = {TCOD_DARKER_SEA}; const TCOD_color_t TCOD_darker_turquoise = {TCOD_DARKER_TURQUOISE}; const TCOD_color_t TCOD_darker_cyan = {TCOD_DARKER_CYAN}; const TCOD_color_t TCOD_darker_sky = {TCOD_DARKER_SKY}; const TCOD_color_t TCOD_darker_azure = {TCOD_DARKER_AZURE}; const TCOD_color_t TCOD_darker_blue = {TCOD_DARKER_BLUE}; const TCOD_color_t TCOD_darker_han = {TCOD_DARKER_HAN}; const TCOD_color_t TCOD_darker_violet = {TCOD_DARKER_VIOLET}; const TCOD_color_t TCOD_darker_purple = {TCOD_DARKER_PURPLE}; const TCOD_color_t TCOD_darker_fuchsia = {TCOD_DARKER_FUCHSIA}; const TCOD_color_t TCOD_darker_magenta = {TCOD_DARKER_MAGENTA}; const TCOD_color_t TCOD_darker_pink = {TCOD_DARKER_PINK}; const TCOD_color_t TCOD_darker_crimson = {TCOD_DARKER_CRIMSON}; /* darkest colors */ const TCOD_color_t TCOD_darkest_red = {TCOD_DARKEST_RED}; const TCOD_color_t TCOD_darkest_flame = {TCOD_DARKEST_FLAME}; const TCOD_color_t TCOD_darkest_orange = {TCOD_DARKEST_ORANGE}; const TCOD_color_t TCOD_darkest_amber = {TCOD_DARKEST_AMBER}; const TCOD_color_t TCOD_darkest_yellow = {TCOD_DARKEST_YELLOW}; const TCOD_color_t TCOD_darkest_lime = {TCOD_DARKEST_LIME}; const TCOD_color_t TCOD_darkest_chartreuse = {TCOD_DARKEST_CHARTREUSE}; const TCOD_color_t TCOD_darkest_green = {TCOD_DARKEST_GREEN}; const TCOD_color_t TCOD_darkest_sea = {TCOD_DARKEST_SEA}; const TCOD_color_t TCOD_darkest_turquoise = {TCOD_DARKEST_TURQUOISE}; const TCOD_color_t TCOD_darkest_cyan = {TCOD_DARKEST_CYAN}; const TCOD_color_t TCOD_darkest_sky = {TCOD_DARKEST_SKY}; const TCOD_color_t TCOD_darkest_azure = {TCOD_DARKEST_AZURE}; const TCOD_color_t TCOD_darkest_blue = {TCOD_DARKEST_BLUE}; const TCOD_color_t TCOD_darkest_han = {TCOD_DARKEST_HAN}; const TCOD_color_t TCOD_darkest_violet = {TCOD_DARKEST_VIOLET}; const TCOD_color_t TCOD_darkest_purple = {TCOD_DARKEST_PURPLE}; const TCOD_color_t TCOD_darkest_fuchsia = {TCOD_DARKEST_FUCHSIA}; const TCOD_color_t TCOD_darkest_magenta = {TCOD_DARKEST_MAGENTA}; const TCOD_color_t TCOD_darkest_pink = {TCOD_DARKEST_PINK}; const TCOD_color_t TCOD_darkest_crimson = {TCOD_DARKEST_CRIMSON}; /* light colors */ const TCOD_color_t TCOD_light_red = {TCOD_LIGHT_RED}; const TCOD_color_t TCOD_light_flame = {TCOD_LIGHT_FLAME}; const TCOD_color_t TCOD_light_orange = {TCOD_LIGHT_ORANGE}; const TCOD_color_t TCOD_light_amber = {TCOD_LIGHT_AMBER}; const TCOD_color_t TCOD_light_yellow = {TCOD_LIGHT_YELLOW}; const TCOD_color_t TCOD_light_lime = {TCOD_LIGHT_LIME}; const TCOD_color_t TCOD_light_chartreuse = {TCOD_LIGHT_CHARTREUSE}; const TCOD_color_t TCOD_light_green = {TCOD_LIGHT_GREEN}; const TCOD_color_t TCOD_light_sea = {TCOD_LIGHT_SEA}; const TCOD_color_t TCOD_light_turquoise = {TCOD_LIGHT_TURQUOISE}; const TCOD_color_t TCOD_light_cyan = {TCOD_LIGHT_CYAN}; const TCOD_color_t TCOD_light_sky = {TCOD_LIGHT_SKY}; const TCOD_color_t TCOD_light_azure = {TCOD_LIGHT_AZURE}; const TCOD_color_t TCOD_light_blue = {TCOD_LIGHT_BLUE}; const TCOD_color_t TCOD_light_han = {TCOD_LIGHT_HAN}; const TCOD_color_t TCOD_light_violet = {TCOD_LIGHT_VIOLET}; const TCOD_color_t TCOD_light_purple = {TCOD_LIGHT_PURPLE}; const TCOD_color_t TCOD_light_fuchsia = {TCOD_LIGHT_FUCHSIA}; const TCOD_color_t TCOD_light_magenta = {TCOD_LIGHT_MAGENTA}; const TCOD_color_t TCOD_light_pink = {TCOD_LIGHT_PINK}; const TCOD_color_t TCOD_light_crimson = {TCOD_LIGHT_CRIMSON}; /*lighter colors */ const TCOD_color_t TCOD_lighter_red = {TCOD_LIGHTER_RED}; const TCOD_color_t TCOD_lighter_flame = {TCOD_LIGHTER_FLAME}; const TCOD_color_t TCOD_lighter_orange = {TCOD_LIGHTER_ORANGE}; const TCOD_color_t TCOD_lighter_amber = {TCOD_LIGHTER_AMBER}; const TCOD_color_t TCOD_lighter_yellow = {TCOD_LIGHTER_YELLOW}; const TCOD_color_t TCOD_lighter_lime = {TCOD_LIGHTER_LIME}; const TCOD_color_t TCOD_lighter_chartreuse = {TCOD_LIGHTER_CHARTREUSE}; const TCOD_color_t TCOD_lighter_green = {TCOD_LIGHTER_GREEN}; const TCOD_color_t TCOD_lighter_sea = {TCOD_LIGHTER_SEA}; const TCOD_color_t TCOD_lighter_turquoise = {TCOD_LIGHTER_TURQUOISE}; const TCOD_color_t TCOD_lighter_cyan = {TCOD_LIGHTER_CYAN}; const TCOD_color_t TCOD_lighter_sky = {TCOD_LIGHTER_SKY}; const TCOD_color_t TCOD_lighter_azure = {TCOD_LIGHTER_AZURE}; const TCOD_color_t TCOD_lighter_blue = {TCOD_LIGHTER_BLUE}; const TCOD_color_t TCOD_lighter_han = {TCOD_LIGHTER_HAN}; const TCOD_color_t TCOD_lighter_violet = {TCOD_LIGHTER_VIOLET}; const TCOD_color_t TCOD_lighter_purple = {TCOD_LIGHTER_PURPLE}; const TCOD_color_t TCOD_lighter_fuchsia = {TCOD_LIGHTER_FUCHSIA}; const TCOD_color_t TCOD_lighter_magenta = {TCOD_LIGHTER_MAGENTA}; const TCOD_color_t TCOD_lighter_pink = {TCOD_LIGHTER_PINK}; const TCOD_color_t TCOD_lighter_crimson = {TCOD_LIGHTER_CRIMSON}; /* lightest colors */ const TCOD_color_t TCOD_lightest_red = {TCOD_LIGHTEST_RED}; const TCOD_color_t TCOD_lightest_flame = {TCOD_LIGHTEST_FLAME}; const TCOD_color_t TCOD_lightest_orange = {TCOD_LIGHTEST_ORANGE}; const TCOD_color_t TCOD_lightest_amber = {TCOD_LIGHTEST_AMBER}; const TCOD_color_t TCOD_lightest_yellow = {TCOD_LIGHTEST_YELLOW}; const TCOD_color_t TCOD_lightest_lime = {TCOD_LIGHTEST_LIME}; const TCOD_color_t TCOD_lightest_chartreuse = {TCOD_LIGHTEST_CHARTREUSE}; const TCOD_color_t TCOD_lightest_green = {TCOD_LIGHTEST_GREEN}; const TCOD_color_t TCOD_lightest_sea = {TCOD_LIGHTEST_SEA}; const TCOD_color_t TCOD_lightest_turquoise = {TCOD_LIGHTEST_TURQUOISE}; const TCOD_color_t TCOD_lightest_cyan = {TCOD_LIGHTEST_CYAN}; const TCOD_color_t TCOD_lightest_sky = {TCOD_LIGHTEST_SKY}; const TCOD_color_t TCOD_lightest_azure = {TCOD_LIGHTEST_AZURE}; const TCOD_color_t TCOD_lightest_blue = {TCOD_LIGHTEST_BLUE}; const TCOD_color_t TCOD_lightest_han = {TCOD_LIGHTEST_HAN}; const TCOD_color_t TCOD_lightest_violet = {TCOD_LIGHTEST_VIOLET}; const TCOD_color_t TCOD_lightest_purple = {TCOD_LIGHTEST_PURPLE}; const TCOD_color_t TCOD_lightest_fuchsia = {TCOD_LIGHTEST_FUCHSIA}; const TCOD_color_t TCOD_lightest_magenta = {TCOD_LIGHTEST_MAGENTA}; const TCOD_color_t TCOD_lightest_pink = {TCOD_LIGHTEST_PINK}; const TCOD_color_t TCOD_lightest_crimson = {TCOD_LIGHTEST_CRIMSON}; /* desaturated colors */ const TCOD_color_t TCOD_desaturated_red = {TCOD_DESATURATED_RED}; const TCOD_color_t TCOD_desaturated_flame = {TCOD_DESATURATED_FLAME}; const TCOD_color_t TCOD_desaturated_orange = {TCOD_DESATURATED_ORANGE}; const TCOD_color_t TCOD_desaturated_amber = {TCOD_DESATURATED_AMBER}; const TCOD_color_t TCOD_desaturated_yellow = {TCOD_DESATURATED_YELLOW}; const TCOD_color_t TCOD_desaturated_lime = {TCOD_DESATURATED_LIME}; const TCOD_color_t TCOD_desaturated_chartreuse = {TCOD_DESATURATED_CHARTREUSE}; const TCOD_color_t TCOD_desaturated_green = {TCOD_DESATURATED_GREEN}; const TCOD_color_t TCOD_desaturated_sea = {TCOD_DESATURATED_SEA}; const TCOD_color_t TCOD_desaturated_turquoise = {TCOD_DESATURATED_TURQUOISE}; const TCOD_color_t TCOD_desaturated_cyan = {TCOD_DESATURATED_CYAN}; const TCOD_color_t TCOD_desaturated_sky = {TCOD_DESATURATED_SKY}; const TCOD_color_t TCOD_desaturated_azure = {TCOD_DESATURATED_AZURE}; const TCOD_color_t TCOD_desaturated_blue = {TCOD_DESATURATED_BLUE}; const TCOD_color_t TCOD_desaturated_han = {TCOD_DESATURATED_HAN}; const TCOD_color_t TCOD_desaturated_violet = {TCOD_DESATURATED_VIOLET}; const TCOD_color_t TCOD_desaturated_purple = {TCOD_DESATURATED_PURPLE}; const TCOD_color_t TCOD_desaturated_fuchsia = {TCOD_DESATURATED_FUCHSIA}; const TCOD_color_t TCOD_desaturated_magenta = {TCOD_DESATURATED_MAGENTA}; const TCOD_color_t TCOD_desaturated_pink = {TCOD_DESATURATED_PINK}; const TCOD_color_t TCOD_desaturated_crimson = {TCOD_DESATURATED_CRIMSON}; /* metallic */ const TCOD_color_t TCOD_brass = {TCOD_BRASS}; const TCOD_color_t TCOD_copper = {TCOD_COPPER}; const TCOD_color_t TCOD_gold = {TCOD_GOLD}; const TCOD_color_t TCOD_silver = {TCOD_SILVER}; /* miscellaneous */ const TCOD_color_t TCOD_celadon = {TCOD_CELADON}; const TCOD_color_t TCOD_peach = {TCOD_PEACH}; /* color array */ const TCOD_color_t TCOD_colors[TCOD_COLOR_NB][TCOD_COLOR_LEVELS] = { {{TCOD_DESATURATED_RED},{TCOD_LIGHTEST_RED},{TCOD_LIGHTER_RED},{TCOD_LIGHT_RED},{TCOD_RED},{TCOD_DARK_RED},{TCOD_DARKER_RED},{TCOD_DARKEST_RED}}, {{TCOD_DESATURATED_FLAME},{TCOD_LIGHTEST_FLAME},{TCOD_LIGHTER_FLAME},{TCOD_LIGHT_FLAME},{TCOD_FLAME},{TCOD_DARK_FLAME},{TCOD_DARKER_FLAME},{TCOD_DARKEST_FLAME}}, {{TCOD_DESATURATED_ORANGE},{TCOD_LIGHTEST_ORANGE},{TCOD_LIGHTER_ORANGE},{TCOD_LIGHT_ORANGE},{TCOD_ORANGE},{TCOD_DARK_ORANGE},{TCOD_DARKER_ORANGE},{TCOD_DARKEST_ORANGE}}, {{TCOD_DESATURATED_AMBER},{TCOD_LIGHTEST_AMBER},{TCOD_LIGHTER_AMBER},{TCOD_LIGHT_AMBER},{TCOD_AMBER},{TCOD_DARK_AMBER},{TCOD_DARKER_AMBER},{TCOD_DARKEST_AMBER}}, {{TCOD_DESATURATED_YELLOW},{TCOD_LIGHTEST_YELLOW},{TCOD_LIGHTER_YELLOW},{TCOD_LIGHT_YELLOW},{TCOD_YELLOW},{TCOD_DARK_YELLOW},{TCOD_DARKER_YELLOW},{TCOD_DARKEST_YELLOW}}, {{TCOD_DESATURATED_LIME},{TCOD_LIGHTEST_LIME},{TCOD_LIGHTER_LIME},{TCOD_LIGHT_LIME},{TCOD_LIME},{TCOD_DARK_LIME},{TCOD_DARKER_LIME},{TCOD_DARKEST_LIME}}, {{TCOD_DESATURATED_CHARTREUSE},{TCOD_LIGHTEST_CHARTREUSE},{TCOD_LIGHTER_CHARTREUSE},{TCOD_LIGHT_CHARTREUSE},{TCOD_CHARTREUSE},{TCOD_DARK_CHARTREUSE},{TCOD_DARKER_CHARTREUSE},{TCOD_DARKEST_CHARTREUSE}}, {{TCOD_DESATURATED_GREEN},{TCOD_LIGHTEST_GREEN},{TCOD_LIGHTER_GREEN},{TCOD_LIGHT_GREEN},{TCOD_GREEN},{TCOD_DARK_GREEN},{TCOD_DARKER_GREEN},{TCOD_DARKEST_GREEN}}, {{TCOD_DESATURATED_SEA},{TCOD_LIGHTEST_SEA},{TCOD_LIGHTER_SEA},{TCOD_LIGHT_SEA},{TCOD_SEA},{TCOD_DARK_SEA},{TCOD_DARKER_SEA},{TCOD_DARKEST_SEA}}, {{TCOD_DESATURATED_TURQUOISE},{TCOD_LIGHTEST_TURQUOISE},{TCOD_LIGHTER_TURQUOISE},{TCOD_LIGHT_TURQUOISE},{TCOD_TURQUOISE},{TCOD_DARK_TURQUOISE},{TCOD_DARKER_TURQUOISE},{TCOD_DARKEST_TURQUOISE}}, {{TCOD_DESATURATED_CYAN},{TCOD_LIGHTEST_CYAN},{TCOD_LIGHTER_CYAN},{TCOD_LIGHT_CYAN},{TCOD_CYAN},{TCOD_DARK_CYAN},{TCOD_DARKER_CYAN},{TCOD_DARKEST_CYAN}}, {{TCOD_DESATURATED_SKY},{TCOD_LIGHTEST_SKY},{TCOD_LIGHTER_SKY},{TCOD_LIGHT_SKY},{TCOD_SKY},{TCOD_DARK_SKY},{TCOD_DARKER_SKY},{TCOD_DARKEST_SKY}}, {{TCOD_DESATURATED_AZURE},{TCOD_LIGHTEST_AZURE},{TCOD_LIGHTER_AZURE},{TCOD_LIGHT_AZURE},{TCOD_AZURE},{TCOD_DARK_AZURE},{TCOD_DARKER_AZURE},{TCOD_DARKEST_AZURE}}, {{TCOD_DESATURATED_BLUE},{TCOD_LIGHTEST_BLUE},{TCOD_LIGHTER_BLUE},{TCOD_LIGHT_BLUE},{TCOD_BLUE},{TCOD_DARK_BLUE},{TCOD_DARKER_BLUE},{TCOD_DARKEST_BLUE}}, {{TCOD_DESATURATED_HAN},{TCOD_LIGHTEST_HAN},{TCOD_LIGHTER_HAN},{TCOD_LIGHT_HAN},{TCOD_HAN},{TCOD_DARK_HAN},{TCOD_DARKER_HAN},{TCOD_DARKEST_HAN}}, {{TCOD_DESATURATED_VIOLET},{TCOD_LIGHTEST_VIOLET},{TCOD_LIGHTER_VIOLET},{TCOD_LIGHT_VIOLET},{TCOD_VIOLET},{TCOD_DARK_VIOLET},{TCOD_DARKER_VIOLET},{TCOD_DARKEST_VIOLET}}, {{TCOD_DESATURATED_PURPLE},{TCOD_LIGHTEST_PURPLE},{TCOD_LIGHTER_PURPLE},{TCOD_LIGHT_PURPLE},{TCOD_PURPLE},{TCOD_DARK_PURPLE},{TCOD_DARKER_PURPLE},{TCOD_DARKEST_PURPLE}}, {{TCOD_DESATURATED_FUCHSIA},{TCOD_LIGHTEST_FUCHSIA},{TCOD_LIGHTER_FUCHSIA},{TCOD_LIGHT_FUCHSIA},{TCOD_FUCHSIA},{TCOD_DARK_FUCHSIA},{TCOD_DARKER_FUCHSIA},{TCOD_DARKEST_FUCHSIA}}, {{TCOD_DESATURATED_MAGENTA},{TCOD_LIGHTEST_MAGENTA},{TCOD_LIGHTER_MAGENTA},{TCOD_LIGHT_MAGENTA},{TCOD_MAGENTA},{TCOD_DARK_MAGENTA},{TCOD_DARKER_MAGENTA},{TCOD_DARKEST_MAGENTA}}, {{TCOD_DESATURATED_PINK},{TCOD_LIGHTEST_PINK},{TCOD_LIGHTER_PINK},{TCOD_LIGHT_PINK},{TCOD_PINK},{TCOD_DARK_PINK},{TCOD_DARKER_PINK},{TCOD_DARKEST_PINK}}, {{TCOD_DESATURATED_CRIMSON},{TCOD_LIGHTEST_CRIMSON},{TCOD_LIGHTER_CRIMSON},{TCOD_LIGHT_CRIMSON},{TCOD_CRIMSON},{TCOD_DARK_CRIMSON},{TCOD_DARKER_CRIMSON},{TCOD_DARKEST_CRIMSON}} }; TCOD_color_t TCOD_color_RGB(uint8_t r, uint8_t g, uint8_t b) { TCOD_color_t ret = { r, g, b }; return ret; } TCOD_color_t TCOD_color_HSV(float h, float s, float v) { TCOD_color_t ret; int i; float f, p, q, t; if( s == 0 ) { /* achromatic (grey) */ ret.r = ret.g = ret.b = (uint8_t)(v*255.0f+0.5f); } else { while (h < 0.0f) h += 360.0f; /*for H < 0 */ while (h >= 360.0f) h -= 360.0f; /*for H >= 360 */ h /= 60; i = (int)(h); /*hue sector 0-5 */ f = h - i; /* factorial part of h */ p = v * ( 1 - s ); q = v * ( 1 - s * f ); t = v * ( 1 - s * ( 1 - f ) ); switch (i) { case 0: ret.r = (uint8_t)(v*255.0f+0.5f); ret.g = (uint8_t)(t*255.0f+0.5f); ret.b = (uint8_t)(p*255.0f+0.5f); break; case 1: ret.r = (uint8_t)(q*255.0f+0.5f); ret.g = (uint8_t)(v*255.0f+0.5f); ret.b = (uint8_t)(p*255.0f+0.5f); break; case 2: ret.r = (uint8_t)(p*255.0f+0.5f); ret.g = (uint8_t)(v*255.0f+0.5f); ret.b = (uint8_t)(t*255.0f+0.5f); break; case 3: ret.r = (uint8_t)(p*255.0f+0.5f); ret.g = (uint8_t)(q*255.0f+0.5f); ret.b = (uint8_t)(v*255.0f+0.5f); break; case 4: ret.r = (uint8_t)(t*255.0f+0.5f); ret.g = (uint8_t)(p*255.0f+0.5f); ret.b = (uint8_t)(v*255.0f+0.5f); break; default: ret.r = (uint8_t)(v*255.0f+0.5f); ret.g = (uint8_t)(p*255.0f+0.5f); ret.b = (uint8_t)(q*255.0f+0.5f); break; } } return ret; } bool TCOD_color_equals (TCOD_color_t c1, TCOD_color_t c2) { return (c1.r == c2.r && c1.g == c2.g && c1.b == c2.b); } TCOD_color_t TCOD_color_add (TCOD_color_t c1, TCOD_color_t c2) { TCOD_color_t ret; int r,g,b; r = (int)(c1.r) + c2.r; g = (int)(c1.g) + c2.g; b = (int)(c1.b) + c2.b; r=MIN(255,r); g=MIN(255,g); b=MIN(255,b); ret.r=(uint8_t)r; ret.g=(uint8_t)g; ret.b=(uint8_t)b; return ret; } TCOD_color_t TCOD_color_subtract (TCOD_color_t c1, TCOD_color_t c2) { TCOD_color_t ret; int r,g,b; r = (int)(c1.r) - c2.r; g = (int)(c1.g) - c2.g; b = (int)(c1.b) - c2.b; r=MAX(0,r); g=MAX(0,g); b=MAX(0,b); ret.r=(uint8_t)r; ret.g=(uint8_t)g; ret.b=(uint8_t)b; return ret; } TCOD_color_t TCOD_color_multiply (TCOD_color_t c1, TCOD_color_t c2) { TCOD_color_t ret; ret.r=(uint8_t)(((int)c1.r)*c2.r/255); ret.g=(uint8_t)(((int)c1.g)*c2.g/255); ret.b=(uint8_t)(((int)c1.b)*c2.b/255); return ret; } TCOD_color_t TCOD_color_multiply_scalar (TCOD_color_t c1, float value) { TCOD_color_t ret; int r,g,b; r = (int)(c1.r * value); g = (int)(c1.g * value); b = (int)(c1.b * value); ret.r=(uint8_t)CLAMP(0,255,r); ret.g=(uint8_t)CLAMP(0,255,g); ret.b=(uint8_t)CLAMP(0,255,b); return ret; } TCOD_color_t TCOD_color_lerp(TCOD_color_t c1, TCOD_color_t c2, float coef) { TCOD_color_t ret; ret.r=(uint8_t)(c1.r+(c2.r-c1.r)*coef); ret.g=(uint8_t)(c1.g+(c2.g-c1.g)*coef); ret.b=(uint8_t)(c1.b+(c2.b-c1.b)*coef); return ret; } /* 0<= h < 360, 0 <= s <= 1, 0 <= v <= 1 */ void TCOD_color_set_HSV(TCOD_color_t *c, float h, float s, float v) { int i; float f, p, q, t; if( s == 0.0f ) { /* achromatic (grey) */ c->r = c->g = c->b = (uint8_t)(v*255.0f+0.5f); return; } while (h < 0.0f) h += 360.0f; /*for H < 0 */ while (h >= 360.0f) h -= 360.0f; /*for H >= 360 */ h /= 60.0f; /* sector 0 to 5 */ i = (int)floor( h ); f = h - i; /* factorial part of h */ p = v * ( 1 - s ); q = v * ( 1 - s * f ); t = v * ( 1 - s * ( 1 - f ) ); switch( i ) { case 0: c->r = (uint8_t)(v*255.0f+0.5f); c->g = (uint8_t)(t*255.0f+0.5f); c->b = (uint8_t)(p*255.0f+0.5f); break; case 1: c->r = (uint8_t)(q*255.0f+0.5f); c->g = (uint8_t)(v*255.0f+0.5f); c->b = (uint8_t)(p*255.0f+0.5f); break; case 2: c->r = (uint8_t)(p*255.0f+0.5f); c->g = (uint8_t)(v*255.0f+0.5f); c->b = (uint8_t)(t*255.0f+0.5f); break; case 3: c->r = (uint8_t)(p*255.0f+0.5f); c->g = (uint8_t)(q*255.0f+0.5f); c->b = (uint8_t)(v*255.0f+0.5f); break; case 4: c->r = (uint8_t)(t*255.0f+0.5f); c->g = (uint8_t)(p*255.0f+0.5f); c->b = (uint8_t)(v*255.0f+0.5f); break; default: c->r = (uint8_t)(v*255.0f+0.5f); c->g = (uint8_t)(p*255.0f+0.5f); c->b = (uint8_t)(q*255.0f+0.5f); break; } } void TCOD_color_get_HSV(TCOD_color_t c, float *h, float *s, float *v) { uint8_t imax,imin; float min, max, delta; imax = ( c.r > c.g ? ( c.r > c.b ? c.r : c.b ) : ( c.g > c.b ? c.g : c.b) ); imin = ( c.r < c.g ? ( c.r < c.b ? c.r : c.b ) : ( c.g < c.b ? c.g : c.b) ); max = imax/255.0f; min = imin/255.0f; *v = max; /* v */ delta = max - min; if( max != 0.0f ) *s = delta / max; /* s */ else { *s = 0.0f; /* s */ *h = 0.0f; /* h */ return; } if( c.r == imax ) *h = ( c.g - c.b ) / (255.0f * delta); /* between yellow & magenta */ else if( c.g == imax ) *h = 2.0f + ( c.b - c.r ) / (255.0f * delta); /* between cyan & yellow */ else *h = 4.0f + ( c.r - c.g ) / (255.0f * delta); /* between magenta & cyan */ *h *= 60.0f; /* degrees */ if( *h < 0 ) *h += 360.0f; } float TCOD_color_get_hue (TCOD_color_t c) { uint8_t max = MAX(c.r,MAX(c.g,c.b)); uint8_t min = MIN(c.r,MIN(c.g,c.b)); float delta = (float)max - (float)min; float ret; if (delta == 0.0f) ret = 0.0f; /*achromatic, including black */ else { if (c.r == max) ret = (float)(c.g - c.b) / delta; else if (c.g == max) ret = 2.0f + (float)(c.b - c.r) / delta; else ret = 4.0f + (float)(c.r - c.g) / delta; ret *= 60.0f; if (ret < 0.0f) ret += 360.0f; if (ret >= 360.0f) ret -= 360.0f; } return ret; } void TCOD_color_set_hue (TCOD_color_t *c, float h) { float obsolete, s, v; TCOD_color_get_HSV(*c,&obsolete,&s,&v); *c = TCOD_color_HSV(h,s,v); } float TCOD_color_get_saturation (TCOD_color_t c) { float max = (float)(MAX(c.r,MAX(c.g,c.b)))/255.0f; float min = (float)(MIN(c.r,MIN(c.g,c.b)))/255.0f; float delta = max - min; if (max == 0.0f) return 0.0f; else return delta/max; } void TCOD_color_set_saturation (TCOD_color_t *c, float s) { float h, obsolete, v; TCOD_color_get_HSV(*c,&h,&obsolete,&v); *c = TCOD_color_HSV(h,s,v); } float TCOD_color_get_value (TCOD_color_t c) { return (float)(MAX(c.r,MAX(c.g,c.b)))/255.0f; } void TCOD_color_set_value (TCOD_color_t *c, float v) { float h, s, obsolete; TCOD_color_get_HSV(*c,&h,&s,&obsolete); *c = TCOD_color_HSV(h,s,v); } void TCOD_color_shift_hue (TCOD_color_t *c, float hshift) { float h, s, v; if (hshift == 0.0f) return; TCOD_color_get_HSV(*c,&h,&s,&v); *c = TCOD_color_HSV(h+hshift,s,v); } void TCOD_color_scale_HSV (TCOD_color_t *c, float scoef, float vcoef) { float h, s, v; TCOD_color_get_HSV(*c,&h,&s,&v); s = CLAMP(0.0f,1.0f,s*scoef); v = CLAMP(0.0f,1.0f,v*vcoef); *c = TCOD_color_HSV(h,s,v); } void TCOD_color_gen_map(TCOD_color_t *map, int nb_key, TCOD_color_t const *key_color, int const *key_index) { int segment=0; for (segment=0; segment < nb_key-1; segment++) { int idx_start=key_index[segment]; int idx_end=key_index[segment+1]; int idx; for ( idx=idx_start;idx <= idx_end; idx++) { map[idx]=TCOD_color_lerp(key_color[segment],key_color[segment+1],(float)(idx-idx_start)/(idx_end-idx_start)); } } } libtcod-1.6.4+dfsg/src/console.cpp000066400000000000000000000324551321276576200170420ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #ifdef TCOD_CONSOLE_SUPPORT TCODConsole * TCODConsole::root = NULL; TCODConsole::TCODConsole() {} TCODConsole::TCODConsole(int w, int h) { data = TCOD_console_new(w,h); } TCODConsole::TCODConsole(const char *filename) { data = TCOD_console_from_file(filename); } bool TCODConsole::loadAsc(const char *filename) { return TCOD_console_load_asc(data,filename) != 0; } bool TCODConsole::saveAsc(const char *filename) const { return TCOD_console_save_asc(data,filename) != 0; } bool TCODConsole::saveApf(const char *filename) const { return TCOD_console_save_apf(data,filename) != 0; } bool TCODConsole::loadApf(const char *filename) { return TCOD_console_load_apf(data,filename) != 0; } void TCODConsole::setCustomFont(const char *fontFile, int flags,int nbCharHoriz, int nbCharVertic) { TCOD_console_set_custom_font(fontFile,flags,nbCharHoriz,nbCharVertic); } void TCODConsole::mapAsciiCodeToFont(int asciiCode, int fontCharX, int fontCharY) { TCOD_console_map_ascii_code_to_font(asciiCode,fontCharX,fontCharY); } void TCODConsole::mapAsciiCodesToFont(int firstAsciiCode, int nbCodes, int fontCharX, int fontCharY) { TCOD_console_map_ascii_codes_to_font(firstAsciiCode,nbCodes,fontCharX,fontCharY); } void TCODConsole::mapStringToFont(const char *s, int fontCharX, int fontCharY) { TCOD_console_map_string_to_font(s, fontCharX, fontCharY); } void TCODConsole::setDirty(int x, int y, int w, int h) { TCOD_console_set_dirty(x,y,w,h); } TCOD_key_t TCODConsole::checkForKeypress(int flags) { return TCOD_sys_check_for_keypress(flags); } TCOD_key_t TCODConsole::waitForKeypress(bool flush) { return TCOD_sys_wait_for_keypress(flush); } bool TCODConsole::isWindowClosed() { return TCOD_console_is_window_closed() != 0; } bool TCODConsole::hasMouseFocus() { return TCOD_console_has_mouse_focus() != 0; } bool TCODConsole::isActive() { return TCOD_console_is_active() != 0; } int TCODConsole::getWidth() const { return TCOD_console_get_width(data); } int TCODConsole::getHeight() const { return TCOD_console_get_height(data); } void TCODConsole::setColorControl(TCOD_colctrl_t con, const TCODColor &fore, const TCODColor &back) { TCOD_color_t b={back.r,back.g,back.b},f={fore.r,fore.g,fore.b}; TCOD_console_set_color_control(con,f,b); } TCODColor TCODConsole::getDefaultBackground() const { TCOD_color_t c= TCOD_console_get_default_background(data); TCODColor ret; ret.r=c.r; ret.g=c.g; ret.b=c.b; return ret; } TCODColor TCODConsole::getDefaultForeground() const { return TCOD_console_get_default_foreground(data); } void TCODConsole::setDefaultBackground(TCODColor back) { TCOD_color_t b={back.r,back.g,back.b}; TCOD_console_set_default_background(data,b); } void TCODConsole::setDefaultForeground(TCODColor fore) { TCOD_color_t b={fore.r,fore.g,fore.b}; TCOD_console_set_default_foreground(data,b); } #ifndef TCOD_BARE void TCODConsole::setWindowTitle(const char *title) { TCOD_sys_set_window_title(title); } #endif void TCODConsole::initRoot(int w, int h, const char *title, bool fullscreen, TCOD_renderer_t renderer) { TCODConsole *con=new TCODConsole(); TCOD_console_init_root(w,h,title,fullscreen,renderer); con->data=TCOD_ctx.root; TCODConsole::root=con; } void TCODConsole::setFullscreen(bool fullscreen) { TCOD_console_set_fullscreen(fullscreen); } bool TCODConsole::isFullscreen() { return TCOD_console_is_fullscreen() != 0; } void TCODConsole::setBackgroundFlag(TCOD_bkgnd_flag_t bkgnd_flag) { TCOD_console_set_background_flag(data,bkgnd_flag); } TCOD_bkgnd_flag_t TCODConsole::getBackgroundFlag() const { return TCOD_console_get_background_flag(data); } void TCODConsole::setAlignment(TCOD_alignment_t alignment) { TCOD_console_set_alignment(data,alignment); } TCOD_alignment_t TCODConsole::getAlignment() const { return TCOD_console_get_alignment(data); } TCODConsole::~TCODConsole() { TCOD_console_delete(data); } void TCODConsole::blit(const TCODConsole *srcCon,int xSrc, int ySrc, int wSrc, int hSrc, TCODConsole *dstCon, int xDst, int yDst, float foreground_alpha, float background_alpha) { TCOD_console_blit(srcCon->data,xSrc,ySrc,wSrc,hSrc,dstCon->data,xDst,yDst,foreground_alpha, background_alpha); } void TCODConsole::flush() { TCOD_console_flush(); } void TCODConsole::setFade(uint8_t val, const TCODColor &fade) { TCOD_color_t f= {fade.r,fade.g,fade.b}; TCOD_console_set_fade(val,f); } uint8_t TCODConsole::getFade() { return TCOD_console_get_fade(); } TCODColor TCODConsole::getFadingColor() { return TCOD_console_get_fading_color(); } void TCODConsole::putChar(int x, int y, int c, TCOD_bkgnd_flag_t flag) { TCOD_console_put_char(data,x,y,c,flag); } void TCODConsole::putCharEx(int x, int y, int c, const TCODColor &fore, const TCODColor &back) { TCOD_color_t f={fore.r,fore.g,fore.b}; TCOD_color_t b={back.r,back.g,back.b}; TCOD_console_put_char_ex(data,x,y,c,f,b); } void TCODConsole::clear() { TCOD_console_clear(data); } TCODColor TCODConsole::getCharBackground(int x, int y) const { return TCOD_console_get_char_background(data,x,y); } void TCODConsole::setCharForeground(int x,int y, const TCODColor &col) { TCOD_color_t c={col.r,col.g,col.b}; TCOD_console_set_char_foreground(data,x,y,c); } TCODColor TCODConsole::getCharForeground(int x, int y) const { return TCOD_console_get_char_foreground(data,x,y); } int TCODConsole::getChar(int x, int y) const { return TCOD_console_get_char(data,x,y); } void TCODConsole::setCharBackground(int x, int y, const TCODColor &col, TCOD_bkgnd_flag_t flag) { TCOD_color_t c={col.r,col.g,col.b}; TCOD_console_set_char_background(data,x,y,c,flag); } void TCODConsole::setChar(int x, int y, int c) { TCOD_console_set_char(data,x,y,c); } void TCODConsole::rect(int x,int y, int rw, int rh, bool clear, TCOD_bkgnd_flag_t flag) { TCOD_console_rect(data,x,y,rw,rh,clear,flag); } void TCODConsole::hline(int x,int y, int l, TCOD_bkgnd_flag_t flag) { TCOD_console_hline(data,x,y,l,flag); } void TCODConsole::vline(int x,int y, int l, TCOD_bkgnd_flag_t flag) { TCOD_console_vline(data,x,y,l,flag); } /* TCODImage *TCODConsole::getForegroundColorImage() { return new TCODImage(TCOD_console_get_foreground_color_image(data)); } TCODImage *TCODConsole::getBackgroundColorImage() { return new TCODImage(TCOD_console_get_background_color_image(data)); } */ void TCODConsole::printFrame(int x,int y,int w,int h, bool empty, TCOD_bkgnd_flag_t flag, const char *fmt , ...) { if ( fmt ) { va_list ap; va_start(ap,fmt); TCOD_console_print_frame(data,x,y,w,h,empty,flag,TCOD_console_vsprint(fmt,ap)); va_end(ap); } else { TCOD_console_print_frame(data,x,y,w,h,empty,flag,NULL); } } void TCODConsole::print(int x, int y, const char *fmt, ...) { va_list ap; TCOD_console_data_t *dat=(TCOD_console_data_t *)data; TCOD_IFNOT ( dat != NULL ) return; va_start(ap,fmt); TCOD_console_print_internal(data,x,y,0,0,dat->bkgnd_flag,dat->alignment, TCOD_console_vsprint(fmt,ap),false,false); va_end(ap); } void TCODConsole::printEx(int x, int y, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment, const char *fmt, ...) { va_list ap; va_start(ap,fmt); TCOD_console_print_internal(data,x,y,0,0,flag,alignment,TCOD_console_vsprint(fmt,ap),false,false); va_end(ap); } /* void TCODConsole::printLine(int x, int y, TCOD_bkgnd_flag_t flag, TCOD_print_location_t location, const char *fmt, ...) { va_list ap; va_start(ap,fmt); switch(location) { case TCOD_PRINT_LEFT: TCOD_console_print(data,x,y,getWidth()-x,getHeight()-y,flag,LEFT,TCOD_console_vsprint(fmt,ap),false,false); break; case TCOD_PRINT_RIGHT: TCOD_console_print(data,x,y,x+1,getHeight()-y,flag,RIGHT,TCOD_console_vsprint(fmt,ap),false,false); break; case TCOD_PRINT_CENTER: TCOD_console_print(data,x,y,getWidth(),getHeight()-y,flag,CENTER,TCOD_console_vsprint(fmt,ap),false,false); break; default: TCOD_ASSERT(0); break; } va_end(ap); } */ int TCODConsole::printRect(int x, int y, int w, int h, const char *fmt, ...) { va_list ap; TCOD_console_data_t *dat=(TCOD_console_data_t *)data; TCOD_IFNOT ( dat != NULL ) return 0; va_start(ap,fmt); int ret = TCOD_console_print_internal(data,x,y,w,h,dat->bkgnd_flag,dat->alignment,TCOD_console_vsprint(fmt,ap),true,false); va_end(ap); return ret; } int TCODConsole::printRectEx(int x, int y, int w, int h, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment, const char *fmt, ...) { va_list ap; va_start(ap,fmt); int ret = TCOD_console_print_internal(data,x,y,w,h,flag,alignment,TCOD_console_vsprint(fmt,ap),true,false); va_end(ap); return ret; } int TCODConsole::getHeightRect(int x, int y, int w, int h, const char *fmt, ...) { va_list ap; va_start(ap,fmt); int ret = TCOD_console_print_internal(data,x,y,w,h,TCOD_BKGND_NONE,TCOD_LEFT,TCOD_console_vsprint(fmt,ap),true,true); va_end(ap); return ret; } bool TCODConsole::isKeyPressed(TCOD_keycode_t key) { return TCOD_console_is_key_pressed(key) != 0; } void TCODConsole::setKeyColor(const TCODColor &col) { TCOD_color_t c={col.r,col.g,col.b}; TCOD_console_set_key_color(data,c); } void TCODConsole::credits() { TCOD_console_credits(); } void TCODConsole::resetCredits() { TCOD_console_credits_reset(); } bool TCODConsole::renderCredits(int x, int y, bool alpha) { return TCOD_console_credits_render(x,y,alpha) != 0; } #ifndef NO_UNICODE void TCODConsole::mapStringToFont(const wchar_t *s, int fontCharX, int fontCharY) { TCOD_console_map_string_to_font_utf(s, fontCharX, fontCharY); } void TCODConsole::print(int x, int y, const wchar_t *fmt, ...) { va_list ap; TCOD_console_data_t *dat=(TCOD_console_data_t *)data; TCOD_IFNOT ( dat != NULL ) return; va_start(ap,fmt); TCOD_console_print_internal_utf(data,x,y,0,0,dat->bkgnd_flag,dat->alignment,TCOD_console_vsprint_utf(fmt,ap),false,false); va_end(ap); } void TCODConsole::printEx(int x, int y, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment, const wchar_t *fmt, ...) { va_list ap; va_start(ap,fmt); TCOD_console_print_internal_utf(data,x,y,0,0,flag,alignment,TCOD_console_vsprint_utf(fmt,ap),false,false); va_end(ap); } int TCODConsole::printRect(int x, int y, int w, int h, const wchar_t *fmt, ...) { va_list ap; TCOD_console_data_t *dat=(TCOD_console_data_t *)data; TCOD_IFNOT ( dat != NULL ) return 0; va_start(ap,fmt); int ret = TCOD_console_print_internal_utf(data,x,y,w,h,dat->bkgnd_flag,dat->alignment, TCOD_console_vsprint_utf(fmt,ap),true,false); va_end(ap); return ret; } int TCODConsole::printRectEx(int x, int y, int w, int h, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment, const wchar_t *fmt, ...) { va_list ap; va_start(ap,fmt); int ret = TCOD_console_print_internal_utf(data,x,y,w,h,flag,alignment, TCOD_console_vsprint_utf(fmt,ap),true,false); va_end(ap); return ret; } int TCODConsole::getHeightRect(int x, int y, int w, int h, const wchar_t *fmt, ...) { va_list ap; va_start(ap,fmt); int ret = TCOD_console_print_internal_utf(data,x,y,w,h,TCOD_BKGND_NONE,TCOD_LEFT,TCOD_console_vsprint_utf(fmt,ap),true,true); va_end(ap); return ret; } // color control string formatting utilities for swigged language // ctrl = TCOD_COLCTRL_1...TCOD_COLCTRL_5 or TCOD_COLCTRL_STOP #define NB_BUFFERS 10 const char *TCODConsole::getColorControlString( TCOD_colctrl_t ctrl ) { static char buf[NB_BUFFERS][2]; static int buf_nb=0; const char *ret; buf[buf_nb][0]=ctrl; buf[buf_nb][1]=0; ret = (const char *)(&buf[buf_nb][0]); buf_nb = (buf_nb+1) % NB_BUFFERS; return ret; } // ctrl = TCOD_COLCTRL_FORE_RGB or TCOD_COLCTRL_BACK_RGB const char *TCODConsole::getRGBColorControlString( TCOD_colctrl_t ctrl, const TCODColor & col ) { static char buf[NB_BUFFERS][5]; static int buf_nb=0; const char *ret; buf[buf_nb][0]=ctrl; buf[buf_nb][1]=col.r; buf[buf_nb][2]=col.g; buf[buf_nb][3]=col.b; buf[buf_nb][4]=0; ret = (const char *)(&buf[buf_nb][0]); buf_nb = (buf_nb+1) % NB_BUFFERS; return ret; } #endif #endif /* TCOD_CONSOLE_SUPPORT */ libtcod-1.6.4+dfsg/src/console_c.c000066400000000000000000002021431321276576200167750ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #ifndef NO_UNICODE #include #include #endif #include #include #include #include #include #ifdef TCOD_CONSOLE_SUPPORT #if defined( TCOD_VISUAL_STUDIO ) static const char *version_string ="libtcod "TCOD_STRVERSION; #else static const char *version_string __attribute__((unused)) ="libtcod "TCOD_STRVERSION; #endif TCOD_internal_context_t TCOD_ctx={ /* number of characters in the bitmap font */ 16,16, /* font type and layout */ false,false,false, /* character size in font */ 8,8, "terminal.png","", NULL,NULL,NULL,0,false,0,0,0,0,0,0, #ifdef TCOD_SDL2 /* default renderer to use */ TCOD_RENDERER_GLSL, NULL, #endif /* fading data */ {0,0,0},255, /*key state*/ {0}, /* window closed ? */ false, /* mouse focus ? */ false, /* application active ? */ true, }; static TCOD_color_t color_control_fore[TCOD_COLCTRL_NUMBER]; static TCOD_color_t color_control_back[TCOD_COLCTRL_NUMBER]; void TCOD_console_set_color_control(TCOD_colctrl_t con, TCOD_color_t fore, TCOD_color_t back) { TCOD_IFNOT(con >= TCOD_COLCTRL_1 && con <= TCOD_COLCTRL_NUMBER ) return; color_control_fore[con-1]=fore; color_control_back[con-1]=back; } TCOD_console_t TCOD_console_new(int w, int h) { TCOD_IFNOT(w > 0 && h > 0 ) { return NULL; } else { TCOD_console_data_t *con=(TCOD_console_data_t *)calloc(sizeof(TCOD_console_data_t),1); con->w=w; con->h=h; TCOD_console_init(con,NULL,false); if(TCOD_ctx.root) { con->alignment=TCOD_ctx.root->alignment; con->bkgnd_flag=TCOD_ctx.root->bkgnd_flag; } return (TCOD_console_t)con; } } TCOD_key_t TCOD_console_check_for_keypress(int flags) { return TCOD_sys_check_for_keypress(flags); } TCOD_key_t TCOD_console_wait_for_keypress(bool flush) { return TCOD_sys_wait_for_keypress(flush); } bool TCOD_console_is_window_closed(void) { return TCOD_ctx.is_window_closed; } bool TCOD_console_has_mouse_focus(void) { return TCOD_ctx.app_has_mouse_focus; } #ifdef TCOD_SDL2 bool TCOD_console_is_active(void) { return TCOD_ctx.app_is_active; } #endif void TCOD_console_set_window_title(const char *title) { TCOD_sys_set_window_title(title); } void TCOD_console_set_fullscreen(bool fullscreen) { TCOD_IFNOT(TCOD_ctx.root != NULL) return; TCOD_sys_set_fullscreen(fullscreen); TCOD_ctx.fullscreen=fullscreen; } bool TCOD_console_is_fullscreen(void) { return TCOD_ctx.fullscreen; } void TCOD_console_set_background_flag(TCOD_console_t con,TCOD_bkgnd_flag_t flag) { TCOD_console_data_t *dat=con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT ( dat != NULL ) return; dat->bkgnd_flag=flag; } TCOD_bkgnd_flag_t TCOD_console_get_background_flag(TCOD_console_t con) { TCOD_console_data_t *dat=con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT ( dat != NULL ) return TCOD_BKGND_NONE; return dat->bkgnd_flag; } void TCOD_console_set_alignment(TCOD_console_t con,TCOD_alignment_t alignment) { TCOD_console_data_t *dat=con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT ( dat != NULL ) return; dat->alignment=alignment; } TCOD_alignment_t TCOD_console_get_alignment(TCOD_console_t con) { TCOD_console_data_t *dat=con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT ( dat != NULL ) return TCOD_LEFT; return dat->alignment; } static void TCOD_console_data_free(TCOD_console_data_t *dat) { if (dat->fg_colors) TCOD_image_delete(dat->fg_colors); if (dat->bg_colors) TCOD_image_delete(dat->bg_colors); free(dat->ch_array); } void TCOD_console_delete(TCOD_console_t con) { TCOD_console_data_t *dat=(TCOD_console_data_t *)(con); if (! dat ) { dat=TCOD_ctx.root; TCOD_sys_uninit(); TCOD_ctx.root=NULL; } TCOD_console_data_free(dat); free(dat); } void TCOD_console_blit(TCOD_console_t srcCon, int xSrc, int ySrc, int wSrc, int hSrc, TCOD_console_t dstCon, int xDst, int yDst, float foreground_alpha, float background_alpha) { TCOD_console_data_t *src = srcCon ? (TCOD_console_data_t *)srcCon : TCOD_ctx.root; TCOD_console_data_t *dst = dstCon ? (TCOD_console_data_t *)dstCon : TCOD_ctx.root; TCOD_color_t *srcFgColors, *srcBgColors, *dstFgColors, *dstBgColors; bool srcHasKeyColor; TCOD_color_t srcKeyColor; int cx, cy; if (wSrc == 0) wSrc = src->w; if (hSrc == 0) hSrc = src->h; TCOD_IFNOT(wSrc > 0 && hSrc > 0) return; TCOD_IFNOT(xDst + wSrc >= 0 && yDst + hSrc >= 0 && xDst < dst->w && yDst < dst->h) return; TCOD_image_get_key_data(src->bg_colors, &srcHasKeyColor, &srcKeyColor); srcFgColors = TCOD_image_get_colors(src->fg_colors); srcBgColors = TCOD_image_get_colors(src->bg_colors); dstFgColors = TCOD_image_get_colors(dst->fg_colors); dstBgColors = TCOD_image_get_colors(dst->bg_colors); for (cx = xSrc; cx < xSrc + wSrc; cx++) { for (cy = ySrc; cy < ySrc + hSrc; cy++) { /* check if we're outside the dest console */ int dx = cx - xSrc + xDst; int dy = cy - ySrc + yDst; int dst_idx = dy * dst->w + dx; int src_idx = cy * src->w + cx; int srcChar, dstChar; TCOD_color_t srcFgColor, srcBgColor, dstFgColor, dstBgColor; if ((unsigned)cx >= (unsigned)src->w || (unsigned)cy >= (unsigned)src->h) continue; if ((unsigned)dx >= (unsigned)dst->w || (unsigned)dy >= (unsigned)dst->h) continue; srcChar = src->ch_array[src_idx]; srcFgColor = srcFgColors[src_idx]; srcBgColor = srcBgColors[src_idx]; /* check if source pixel is transparent */ if (srcHasKeyColor && srcBgColor.r == srcKeyColor.r && srcBgColor.g == srcKeyColor.g && srcBgColor.b == srcKeyColor.b) continue; if (foreground_alpha == 1.0f && background_alpha == 1.0f) { dstChar = srcChar; dstFgColor = srcFgColor; dstBgColor = srcBgColor; } else { dstChar = dst->ch_array[dst_idx]; dstFgColor = dstFgColors[dst_idx]; dstBgColor = dstBgColors[dst_idx]; dstBgColor = TCOD_color_lerp(dstBgColor, srcBgColor, background_alpha); if (srcChar == ' ') { dstFgColor = TCOD_color_lerp(dstFgColor, srcBgColor, background_alpha); } else if (dstChar == ' ') { dstChar = srcChar; dstFgColor = TCOD_color_lerp(dstBgColor, srcFgColor, foreground_alpha); } else if (dstChar == srcChar) { dstFgColor = TCOD_color_lerp(dstFgColor, srcFgColor, foreground_alpha); } else { if (foreground_alpha < 0.5f) { dstFgColor = TCOD_color_lerp(dstFgColor, dstBgColor, foreground_alpha * 2); } else { dstChar = srcChar; dstFgColor = TCOD_color_lerp(dstBgColor, srcFgColor, (foreground_alpha - 0.5f) * 2); } } } dstFgColors[dst_idx] = dstFgColor; dstBgColors[dst_idx] = dstBgColor; dst->ch_array[dst_idx] = dstChar; } } TCOD_image_invalidate_mipmaps(dst->fg_colors); TCOD_image_invalidate_mipmaps(dst->bg_colors); } void TCOD_console_flush(void) { TCOD_IFNOT(TCOD_ctx.root != NULL) return; TCOD_sys_flush(true); } void TCOD_console_set_fade(uint8_t val, TCOD_color_t fadecol) { TCOD_ctx.fade=val; TCOD_ctx.fading_color=fadecol; } uint8_t TCOD_console_get_fade(void) { return TCOD_ctx.fade; } TCOD_color_t TCOD_console_get_fading_color(void) { return TCOD_ctx.fading_color; } void TCOD_console_put_char(TCOD_console_t con, int x, int y, int c, TCOD_bkgnd_flag_t flag) { int offset; TCOD_console_data_t *dat = con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT(dat != NULL && (unsigned)(x) < (unsigned)dat->w && (unsigned)(y) < (unsigned)dat->h) return; TCOD_IFNOT(c >= 0 && c < TCOD_ctx.max_font_chars) return; offset = y * dat->w + x; dat->ch_array[offset] = c; TCOD_image_put_pixel(dat->fg_colors, x, y, dat->fore); TCOD_console_set_char_background(con, x, y, dat->back, (TCOD_bkgnd_flag_t)flag); } void TCOD_console_put_char_ex(TCOD_console_t con, int x, int y, int c, TCOD_color_t fore, TCOD_color_t back) { int offset; TCOD_console_data_t *dat = con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT(dat != NULL && (unsigned)(x) < (unsigned)dat->w && (unsigned)(y) < (unsigned)dat->h) return; TCOD_IFNOT(c >= 0 && c < TCOD_ctx.max_font_chars) return; offset = y * dat->w + x; dat->ch_array[offset] = c; TCOD_image_put_pixel(dat->fg_colors, x, y, fore); TCOD_image_put_pixel(dat->bg_colors, x, y, back); } void TCOD_console_set_dirty(int dx, int dy, int dw, int dh) { TCOD_sys_set_dirty(dx, dy, dw, dh); } void TCOD_console_clear(TCOD_console_t con) { int i; TCOD_console_data_t *dat = con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT(dat != NULL) return; for (i = 0; i < dat->w * dat->h; i++) { dat->ch_array[i] = ' '; } TCOD_image_clear(dat->fg_colors, dat->fore); TCOD_image_clear(dat->bg_colors, dat->back); /* clear the sdl renderer cache */ TCOD_sys_set_dirty(0, 0, dat->w, dat->h); } TCOD_color_t TCOD_console_get_char_background(TCOD_console_t con, int x, int y) { TCOD_console_data_t *dat = con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT(dat != NULL && (unsigned)(x) < (unsigned)dat->w && (unsigned)(y) < (unsigned)dat->h) return TCOD_black; return TCOD_image_get_pixel(dat->bg_colors, x, y); } void TCOD_console_set_char_foreground(TCOD_console_t con, int x, int y, TCOD_color_t col) { TCOD_console_data_t *dat = con ? (TCOD_console_data_t *)con : TCOD_ctx.root; if ((unsigned)(x) >= (unsigned)dat->w || (unsigned)(y) >= (unsigned)dat->h) return; TCOD_IFNOT(dat != NULL && (unsigned)(x) < (unsigned)dat->w && (unsigned)(y) < (unsigned)dat->h) return; TCOD_image_put_pixel(dat->fg_colors, x, y, col); } TCOD_color_t TCOD_console_get_char_foreground(TCOD_console_t con, int x, int y) { TCOD_console_data_t *dat = con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT(dat != NULL && (unsigned)(x) < (unsigned)dat->w && (unsigned)(y) < (unsigned)dat->h) return TCOD_white; return TCOD_image_get_pixel(dat->fg_colors, x, y); } int TCOD_console_get_char(TCOD_console_t con, int x, int y) { TCOD_console_data_t *dat = con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT(dat != NULL && (unsigned)(x) < (unsigned)dat->w && (unsigned)(y) < (unsigned)dat->h) return 0; return dat->ch_array[y * dat->w + x]; } void TCOD_console_set_char_background(TCOD_console_t con, int x, int y, TCOD_color_t col, TCOD_bkgnd_flag_t flag) { TCOD_color_t *back; int newr, newg, newb; int alpha; TCOD_console_data_t *dat = con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT(dat != NULL && (unsigned)(x) < (unsigned)dat->w && (unsigned)(y) < (unsigned)dat->h) return; back = &(TCOD_image_get_colors(dat->bg_colors)[y*dat->w + x]); if (flag == TCOD_BKGND_DEFAULT) flag = dat->bkgnd_flag; switch (flag & 0xff) { case TCOD_BKGND_SET: *back = col; break; case TCOD_BKGND_MULTIPLY: *back = TCOD_color_multiply(*back, col); break; case TCOD_BKGND_LIGHTEN: back->r = MAX(back->r, col.r); back->g = MAX(back->g, col.g); back->b = MAX(back->b, col.b); break; case TCOD_BKGND_DARKEN: back->r = MIN(back->r, col.r); back->g = MIN(back->g, col.g); back->b = MIN(back->b, col.b); break; case TCOD_BKGND_SCREEN: /* newbk = white - (white - oldbk) * (white - curbk) */ back->r = (uint8_t)(255 - (int)(255 - back->r)*(255 - col.r) / 255); back->g = (uint8_t)(255 - (int)(255 - back->g)*(255 - col.g) / 255); back->b = (uint8_t)(255 - (int)(255 - back->b)*(255 - col.b) / 255); break; case TCOD_BKGND_COLOR_DODGE: /* newbk = curbk / (white - oldbk) */ if (back->r != 255) newr = (int)(255 * col.r) / (255 - back->r); else newr = 255; if (back->g != 255) newg = (int)(255 * col.g) / (255 - back->g); else newg = 255; if (back->b != 255) newb = (int)(255 * col.b) / (255 - back->b); else newb = 255; back->r = (uint8_t)CLAMP(0, 255, newr); back->g = (uint8_t)CLAMP(0, 255, newg); back->b = (uint8_t)CLAMP(0, 255, newb); break; case TCOD_BKGND_COLOR_BURN: /* newbk = white - (white - oldbk) / curbk */ if (col.r > 0) newr = 255 - (int)(255 * (255 - back->r)) / col.r; else newr = 0; if (col.g > 0) newg = 255 - (int)(255 * (255 - back->g)) / col.g; else newg = 0; if (col.b > 0) newb = 255 - (int)(255 * (255 - back->b)) / col.b; else newb = 0; back->r = (uint8_t)CLAMP(0, 255, newr); back->g = (uint8_t)CLAMP(0, 255, newg); back->b = (uint8_t)CLAMP(0, 255, newb); break; case TCOD_BKGND_ADD: /* newbk = oldbk + curbk */ newr = (int)(back->r) + col.r; newg = (int)(back->g) + col.g; newb = (int)(back->b) + col.b; back->r = (uint8_t)CLAMP(0, 255, newr); back->g = (uint8_t)CLAMP(0, 255, newg); back->b = (uint8_t)CLAMP(0, 255, newb); break; case TCOD_BKGND_ADDA: alpha = (flag >> 8); /* newbk = oldbk + alpha * curbk */ newr = (int)(back->r) + alpha * col.r / 255; newg = (int)(back->g) + alpha * col.g / 255; newb = (int)(back->b) + alpha * col.b / 255; back->r = (uint8_t)CLAMP(0, 255, newr); back->g = (uint8_t)CLAMP(0, 255, newg); back->b = (uint8_t)CLAMP(0, 255, newb); break; case TCOD_BKGND_BURN: /* newbk = oldbk + curbk - white */ newr = (int)(back->r) + col.r - 255; newg = (int)(back->g) + col.g - 255; newb = (int)(back->b) + col.b - 255; back->r = (uint8_t)CLAMP(0, 255, newr); back->g = (uint8_t)CLAMP(0, 255, newg); back->b = (uint8_t)CLAMP(0, 255, newb); break; case TCOD_BKGND_OVERLAY: /* newbk = curbk.x <= 0.5 ? 2*curbk*oldbk : white - 2*(white-curbk)*(white-oldbk) */ newr = col.r <= 128 ? 2 * (int)(col.r) * back->r / 255 : 255 - 2 * (int)(255 - col.r)*(255 - back->r) / 255; newg = col.g <= 128 ? 2 * (int)(col.g) * back->g / 255 : 255 - 2 * (int)(255 - col.g)*(255 - back->g) / 255; newb = col.b <= 128 ? 2 * (int)(col.b) * back->b / 255 : 255 - 2 * (int)(255 - col.b)*(255 - back->b) / 255; back->r = (uint8_t)CLAMP(0, 255, newr); back->g = (uint8_t)CLAMP(0, 255, newg); back->b = (uint8_t)CLAMP(0, 255, newb); break; case TCOD_BKGND_ALPH: /* newbk = (1.0f-alpha)*oldbk + alpha*(curbk-oldbk) */ alpha = (flag >> 8); *back = TCOD_color_lerp(*back, col, (float)(alpha / 255.0f)); break; default: break; } } void TCOD_console_set_char(TCOD_console_t con, int x, int y, int c) { TCOD_console_data_t *dat = con ? (TCOD_console_data_t *)con : TCOD_ctx.root; if ((unsigned)(x) >= (unsigned)dat->w || (unsigned)(y) >= (unsigned)dat->h) return; dat->ch_array[y * dat->w + x] = c; } static void TCOD_console_clamp(int cx, int cy, int cw, int ch, int *x, int *y, int *w, int *h) { if (*x + *w > cw) *w = cw - *x; if (*y + *h > ch) *h = ch - *y; if (*x < cx) { *w -= cx - *x; *x = cx; } if (*y < cy) { *h -= cy - *y; *y = cy; } } void TCOD_console_rect(TCOD_console_t con, int x, int y, int rw, int rh, bool clear, TCOD_bkgnd_flag_t flag) { int cx, cy; TCOD_console_data_t *dat = con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT(dat != NULL) return; TCOD_ASSERT((unsigned)(x) < (unsigned)dat->w && (unsigned)(y) < (unsigned)dat->h); TCOD_ASSERT(x + rw <= dat->w && y + rh <= dat->h); TCOD_console_clamp(0, 0, dat->w, dat->h, &x, &y, &rw, &rh); TCOD_IFNOT(rw > 0 && rh > 0) return; for (cx = x; cx < x + rw; cx++) { for (cy = y; cyback, flag); if (clear) { dat->ch_array[cx + cy*dat->w] = ' '; } } } } void TCOD_console_hline(TCOD_console_t con,int x,int y, int l, TCOD_bkgnd_flag_t flag) { int i; for (i=x; i< x+l; i++) TCOD_console_put_char(con,i,y,TCOD_CHAR_HLINE,flag); } void TCOD_console_vline(TCOD_console_t con,int x,int y, int l, TCOD_bkgnd_flag_t flag) { int i; for (i=y; i< y+l; i++) TCOD_console_put_char(con,x,i,TCOD_CHAR_VLINE,flag); } char *TCOD_console_vsprint(const char *fmt, va_list ap) { #define NB_BUFFERS 10 #define INITIAL_SIZE 512 /* several static buffers in case the function is used more than once in a single function call */ static char *msg[NB_BUFFERS]={NULL}; static int buflen[NB_BUFFERS]={0}; static int curbuf=0; char *ret; bool ok=false; if (!msg[0]) { int i; for (i=0; i < NB_BUFFERS; i++) { buflen[i]=INITIAL_SIZE; msg[i]=(char *)calloc(sizeof(char),INITIAL_SIZE); } } do { /* warning ! depending on the compiler, vsnprintf return -1 or the expected string length if the buffer is not big enough */ int len = vsnprintf(msg[curbuf],buflen[curbuf],fmt,ap); ok=true; if (len < 0 || len >= buflen[curbuf]) { /* buffer too small. */ if ( len > 0 ) { while ( buflen[curbuf] < len+1 ) buflen[curbuf]*=2; } else { buflen[curbuf]*=2; } free( msg[curbuf] ); msg[curbuf]=(char *)calloc(sizeof(char),buflen[curbuf]); ok=false; } } while (! ok); ret=msg[curbuf]; curbuf = (curbuf+1)%NB_BUFFERS; return ret; } void TCOD_console_print_frame(TCOD_console_t con,int x,int y,int w,int h, bool empty, TCOD_bkgnd_flag_t flag, const char *fmt, ...) { TCOD_console_data_t *dat=con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_console_put_char(con,x,y,TCOD_CHAR_NW,flag); TCOD_console_put_char(con,x+w-1,y,TCOD_CHAR_NE,flag); TCOD_console_put_char(con,x,y+h-1,TCOD_CHAR_SW,flag); TCOD_console_put_char(con,x+w-1,y+h-1,TCOD_CHAR_SE,flag); TCOD_console_hline(con,x+1,y,w-2,flag); TCOD_console_hline(con,x+1,y+h-1,w-2,flag); if ( h > 2 ) { TCOD_console_vline(con,x,y+1,h-2,flag); TCOD_console_vline(con,x+w-1,y+1,h-2,flag); if ( empty ) { TCOD_console_rect(con,x+1,y+1,w-2,h-2,true,flag); } } if (fmt) { va_list ap; int xs; TCOD_color_t tmp; char *title; va_start(ap,fmt); title = TCOD_console_vsprint(fmt,ap); va_end(ap); title[w-3]=0; /* truncate if needed */ xs = x + (w-(int)strlen(title)-2)/2; tmp=dat->back; /* swap colors */ dat->back=dat->fore; dat->fore=tmp; TCOD_console_print_ex(con,xs,y,TCOD_BKGND_SET,TCOD_LEFT," %s ",title); tmp=dat->back; /* swap colors */ dat->back=dat->fore; dat->fore=tmp; } } void TCOD_console_print(TCOD_console_t con,int x, int y, const char *fmt, ...) { va_list ap; TCOD_console_data_t *dat=con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT ( dat != NULL ) return; va_start(ap,fmt); TCOD_console_print_internal(con,x,y,0,0,dat->bkgnd_flag, dat->alignment,TCOD_console_vsprint(fmt,ap), false, false); va_end(ap); } void TCOD_console_print_ex(TCOD_console_t con,int x, int y, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment, const char *fmt, ...) { va_list ap; TCOD_console_data_t *dat=con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT ( dat != NULL ) return; va_start(ap,fmt); TCOD_console_print_internal(con,x,y,0,0,flag,alignment, TCOD_console_vsprint(fmt,ap), false, false); va_end(ap); } int TCOD_console_print_rect(TCOD_console_t con,int x, int y, int w, int h, const char *fmt, ...) { int ret; va_list ap; TCOD_console_data_t *dat=con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT ( dat != NULL ) return 0; va_start(ap,fmt); ret = TCOD_console_print_internal(con,x,y,w,h,dat->bkgnd_flag,dat->alignment, TCOD_console_vsprint(fmt,ap), true, false); va_end(ap); return ret; } int TCOD_console_print_rect_ex(TCOD_console_t con,int x, int y, int w, int h, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment,const char *fmt, ...) { int ret; va_list ap; va_start(ap,fmt); ret = TCOD_console_print_internal(con,x,y,w,h,flag,alignment,TCOD_console_vsprint(fmt,ap), true, false); va_end(ap); return ret; } int TCOD_console_get_height_rect(TCOD_console_t con,int x, int y, int w, int h, const char *fmt, ...) { int ret; va_list ap; va_start(ap,fmt); ret = TCOD_console_print_internal(con,x,y,w,h,TCOD_BKGND_NONE,TCOD_LEFT,TCOD_console_vsprint(fmt,ap), true, true); va_end(ap); return ret; } /* non public methods */ int TCOD_console_stringLength(const unsigned char *s) { int l=0; while (*s) { if ( *s == (int)TCOD_COLCTRL_FORE_RGB || *s == (int)TCOD_COLCTRL_BACK_RGB ) s+=3; else if ( (unsigned)(*s) > (unsigned)TCOD_COLCTRL_STOP ) l++; s++; } return l; } unsigned char * TCOD_console_forward(unsigned char *s,int l) { while ( *s && l > 0 ) { if ( *s == (int)TCOD_COLCTRL_FORE_RGB || *s == (int)TCOD_COLCTRL_BACK_RGB ) s+=3; else if ( *s > (int)TCOD_COLCTRL_STOP ) l--; s++; } return s; } unsigned char *TCOD_console_strchr(unsigned char *s, unsigned char c) { while ( *s && *s != c ) { if ( *s == (int)TCOD_COLCTRL_FORE_RGB || *s == (int)TCOD_COLCTRL_BACK_RGB ) s+=3; s++; } return (*s ? s : NULL); } int TCOD_console_print_internal(TCOD_console_t con,int x,int y, int rw, int rh, TCOD_bkgnd_flag_t flag, TCOD_alignment_t align, char *msg, bool can_split, bool count_only) { unsigned char *c=(unsigned char *)msg; int cx=0,cy=y; int minx,maxx,miny,maxy; TCOD_color_t oldFore; TCOD_color_t oldBack; TCOD_console_data_t *dat=con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT ( dat != NULL && (unsigned)(x) < (unsigned)dat->w && (unsigned)(y) < (unsigned)dat->h ) return 0; TCOD_IFNOT(msg != NULL) return 0; if ( rh == 0 ) rh = dat->h-y; if ( rw == 0 ) switch(align) { case TCOD_LEFT : rw = dat->w-x; break; case TCOD_RIGHT : rw=x+1; break; case TCOD_CENTER : default : rw=dat->w; break; } oldFore=dat->fore; oldBack=dat->back; miny=y; maxy=dat->h-1; if (rh > 0) maxy=MIN(maxy,y+rh-1); switch (align) { case TCOD_LEFT : minx=MAX(0,x); maxx=MIN(dat->w-1,x+rw-1); break; case TCOD_RIGHT : minx=MAX(0,x-rw+1); maxx=MIN(dat->w-1,x); break; case TCOD_CENTER : default : minx=MAX(0,x-rw/2); maxx=MIN(dat->w-1,x+rw/2); break; } do { /* get \n delimited sub-message */ unsigned char *end=TCOD_console_strchr(c,'\n'); char bak=0; int cl; unsigned char *split=NULL; if ( end ) *end=0; cl= TCOD_console_stringLength(c); /* find starting x */ switch (align) { case TCOD_LEFT : cx=x; break; case TCOD_RIGHT : cx=x-cl+1; break; case TCOD_CENTER : cx= x-cl/2;break; } /* check if the string is completely out of the minx,miny,maxx,maxy frame */ if ( cy >= miny && cy <= maxy && cx <= maxx && cx+cl -1 >= minx ) { if ( can_split && cy <= maxy ) { /* if partially out of screen, try to split the sub-message */ if ( cx < minx ) split = TCOD_console_forward(c, align == TCOD_CENTER ? cl-2*(minx-cx) : cl-(minx-cx)); else if ( align == TCOD_CENTER ) { if ( cx + cl/2 > maxx+1 ) split = TCOD_console_forward(c, maxx+1 - cx); } else { if ( cx + cl > maxx+1 ) split = TCOD_console_forward(c, maxx+1 - cx); } } if ( split ) { unsigned char *oldsplit=split; while ( ! isspace(*split) && split > c ) split --; if (end) *end='\n'; if (!isspace(*split) ) { split=oldsplit; } end=split; bak=*split; *split=0; cl=TCOD_console_stringLength(c); switch (align) { case TCOD_LEFT : cx=x; break; case TCOD_RIGHT : cx=x-cl+1; break; case TCOD_CENTER : cx= x-cl/2;break; } } if ( cx < minx ) { /* truncate left part */ c += minx-cx; cl -= minx-cx; cx=minx; } if ( cx + cl > maxx+1 ) { /* truncate right part */ split = TCOD_console_forward(c, maxx+1 - cx); *split=0; } /* render the sub-message */ if ( cy >= 0 && cy < dat->h ) while (*c) { if ( *c >= TCOD_COLCTRL_1 && *c <= TCOD_COLCTRL_NUMBER ) { dat->fore=color_control_fore[(int)(*c)-1]; dat->back=color_control_back[(int)(*c)-1]; } else if ( *c == TCOD_COLCTRL_FORE_RGB ) { c++; dat->fore.r=*c++; dat->fore.g=*c++; dat->fore.b=*c; } else if ( *c == TCOD_COLCTRL_BACK_RGB ) { c++; dat->back.r=*c++; dat->back.g=*c++; dat->back.b=*c; } else if ( *c == TCOD_COLCTRL_STOP ) { dat->fore=oldFore; dat->back=oldBack; } else { if (! count_only) TCOD_console_put_char(con,cx,cy,(int)(*c),flag); cx++; } c++; } } if ( end ) { /* next line */ if ( split && ! isspace(bak) ) { *end=bak; c=end; } else { c=end+1; } cy++; } else c=NULL; } while ( c && cy < dat->h && (rh == 0 || cy < y+rh) ); return cy-y+1; } #ifndef NO_UNICODE wchar_t *TCOD_console_strchr_utf(wchar_t *s, char c) { while ( *s && *s != c ) { if ( *s == (int)TCOD_COLCTRL_FORE_RGB || *s == (int)TCOD_COLCTRL_BACK_RGB ) s+=3; s++; } return (*s ? s : NULL); } void TCOD_console_map_string_to_font_utf(const wchar_t *s, int fontCharX, int fontCharY) { TCOD_IFNOT(s != NULL) return; while (*s) { TCOD_sys_map_ascii_to_font(*s, fontCharX, fontCharY); fontCharX++; if ( fontCharX == TCOD_ctx.fontNbCharHoriz ) { fontCharX=0; fontCharY++; } s++; } } wchar_t *TCOD_console_vsprint_utf(const wchar_t *fmt, va_list ap) { #define NB_BUFFERS 10 #define INITIAL_SIZE 512 /* several static buffers in case the function is used more than once in a single function call */ static wchar_t *msg[NB_BUFFERS]={NULL}; static int buflen[NB_BUFFERS]={0}; static int curbuf=0; wchar_t *ret; bool ok=false; if (!msg[0]) { int i; for (i=0; i < NB_BUFFERS; i++) { buflen[i]=INITIAL_SIZE; msg[i]=(wchar_t *)calloc(sizeof(wchar_t),INITIAL_SIZE); } } do { /* warning ! depending on the compiler, vsnprintf return -1 or the expected string length if the buffer is not big enough */ int len = vsnwprintf(msg[curbuf],buflen[curbuf],fmt,ap); ok=true; if (len < 0 || len >= buflen[curbuf]) { /* buffer too small. */ if ( len > 0 ) { while ( buflen[curbuf] < len+1 ) buflen[curbuf]*=2; } else { buflen[curbuf]*=2; } free( msg[curbuf] ); msg[curbuf]=(wchar_t *)calloc(sizeof(wchar_t),buflen[curbuf]); ok=false; } } while (! ok); ret=msg[curbuf]; curbuf = (curbuf+1)%NB_BUFFERS; return ret; } int TCOD_console_stringLength_utf(const wchar_t *s) { int l=0; while (*s) { if ( *s == (int)TCOD_COLCTRL_FORE_RGB || *s == (int)TCOD_COLCTRL_BACK_RGB ) s+=3; else if ( *s > (int)TCOD_COLCTRL_STOP ) l++; s++; } return l; } wchar_t * TCOD_console_forward_utf(wchar_t *s,int l) { while ( *s && l > 0 ) { if ( *s == (int)TCOD_COLCTRL_FORE_RGB || *s == (int)TCOD_COLCTRL_BACK_RGB ) s+=3; else if ( *s > (int)TCOD_COLCTRL_STOP ) l--; s++; } return s; } int TCOD_console_print_internal_utf(TCOD_console_t con,int x,int y, int rw, int rh, TCOD_bkgnd_flag_t flag, TCOD_alignment_t align, wchar_t *msg, bool can_split, bool count_only) { wchar_t *c=msg; int cx=0,cy=y; int minx,maxx,miny,maxy; TCOD_color_t oldFore; TCOD_color_t oldBack; TCOD_console_data_t *dat=con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT ( dat != NULL && (unsigned)(x) < (unsigned)dat->w && (unsigned)(y) < (unsigned)dat->h ) return 0; TCOD_IFNOT(msg != NULL) return 0; if ( rh == 0 ) rh = dat->h-y; if ( rw == 0 ) switch(align) { case TCOD_LEFT : rw = dat->w-x; break; case TCOD_RIGHT : rw=x+1; break; case TCOD_CENTER : default : rw=dat->w; break; } oldFore=dat->fore; oldBack=dat->back; miny=y; maxy=dat->h-1; if (rh > 0) maxy=MIN(maxy,y+rh-1); switch (align) { case TCOD_LEFT : minx=MAX(0,x); maxx=MIN(dat->w-1,x+rw-1); break; case TCOD_RIGHT : minx=MAX(0,x-rw+1); maxx=MIN(dat->w-1,x); break; case TCOD_CENTER : default : minx=MAX(0,x-rw/2); maxx=MIN(dat->w-1,x+rw/2); break; } do { /* get \n delimited sub-message */ wchar_t *end=TCOD_console_strchr_utf(c,'\n'); wchar_t bak=0; int cl; wchar_t *split=NULL; if ( end ) *end=0; cl= TCOD_console_stringLength_utf(c); /* find starting x */ switch (align) { case TCOD_LEFT : cx=x; break; case TCOD_RIGHT : cx=x-cl+1; break; case TCOD_CENTER : cx= x-cl/2;break; } /* check if the string is completely out of the minx,miny,maxx,maxy frame */ if ( cy >= miny && cy <= maxy && cx <= maxx && cx+cl -1 >= minx ) { if ( can_split && cy < maxy ) { /* if partially out of screen, try to split the sub-message */ if ( cx < minx ) split = TCOD_console_forward_utf(c, align == TCOD_CENTER ? cl-2*(minx-cx) : cl-(minx-cx)); else if ( align==TCOD_CENTER ) { if ( cx + cl/2 > maxx+1 ) split = TCOD_console_forward_utf(c, maxx+1 - cx); } else { if ( cx + cl > maxx+1 ) split = TCOD_console_forward_utf(c, maxx+1 - cx); } } if ( split ) { wchar_t *oldsplit=split; while ( ! iswspace(*split) && split > c ) split --; if (end) *end='\n'; if (!iswspace(*split) ) { split=oldsplit; } end=split; bak=*split; *split=0; cl=TCOD_console_stringLength_utf(c); switch (align) { case TCOD_LEFT : cx=x; break; case TCOD_RIGHT : cx=x-cl+1; break; case TCOD_CENTER : cx= x-cl/2;break; } } if ( cx < minx ) { /* truncate left part */ c += minx-cx; cl -= minx-cx; cx=minx; } if ( cx + cl > maxx+1 ) { /* truncate right part */ split = TCOD_console_forward_utf(c, maxx+1 - cx); *split=0; } /* render the sub-message */ if ( cy >= 0 && cy < dat->h ) while (*c) { if ( *c >= TCOD_COLCTRL_1 && *c <= TCOD_COLCTRL_NUMBER ) { dat->fore=color_control_fore[(int)(*c)-1]; dat->back=color_control_back[(int)(*c)-1]; } else if ( *c == TCOD_COLCTRL_FORE_RGB ) { c++; dat->fore.r=(uint8_t)(*c++); dat->fore.g=(uint8_t)(*c++); dat->fore.b=(uint8_t)(*c); } else if ( *c == TCOD_COLCTRL_BACK_RGB ) { c++; dat->back.r=(uint8_t)(*c++); dat->back.g=(uint8_t)(*c++); dat->back.b=(uint8_t)(*c); } else if ( *c == TCOD_COLCTRL_STOP ) { dat->fore=oldFore; dat->back=oldBack; } else { if (! count_only) TCOD_console_put_char(con,cx,cy,(int)(*c),flag); cx++; } c++; } } if ( end ) { /* next line */ if ( split && ! iswspace(bak) ) { *end=bak; c=end; } else { c=end+1; } cy++; } else c=NULL; } while ( c && cy < dat->h && (rh == 0 || cy < y+rh) ); return cy-y+1; } void TCOD_console_print_utf(TCOD_console_t con,int x, int y, const wchar_t *fmt, ...) { va_list ap; TCOD_console_data_t *dat=con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT ( dat != NULL ) return; va_start(ap,fmt); TCOD_console_print_internal_utf(con,x,y,0,0,dat->bkgnd_flag,dat->alignment, TCOD_console_vsprint_utf(fmt,ap), false, false); va_end(ap); } void TCOD_console_print_ex_utf(TCOD_console_t con,int x, int y, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment, const wchar_t *fmt, ...) { va_list ap; TCOD_console_data_t *dat=con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT ( dat != NULL ) return; va_start(ap,fmt); TCOD_console_print_internal_utf(con,x,y,0,0,flag,alignment,TCOD_console_vsprint_utf(fmt,ap), false, false); va_end(ap); } int TCOD_console_print_rect_utf(TCOD_console_t con,int x, int y, int w, int h, const wchar_t *fmt, ...) { int ret; va_list ap; TCOD_console_data_t *dat=con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT ( dat != NULL ) return 0; va_start(ap,fmt); ret = TCOD_console_print_internal_utf(con,x,y,w,h,dat->bkgnd_flag,dat->alignment, TCOD_console_vsprint_utf(fmt,ap), true, false); va_end(ap); return ret; } int TCOD_console_print_rect_ex_utf(TCOD_console_t con,int x, int y, int w, int h, TCOD_bkgnd_flag_t flag, TCOD_alignment_t alignment, const wchar_t *fmt, ...) { int ret; va_list ap; va_start(ap,fmt); ret=TCOD_console_print_internal_utf(con,x,y,w,h,flag,alignment,TCOD_console_vsprint_utf(fmt,ap), true, false); va_end(ap); return ret; } int TCOD_console_get_height_rect_utf(TCOD_console_t con,int x, int y, int w, int h, const wchar_t *fmt, ...) { int ret; va_list ap; va_start(ap,fmt); ret = TCOD_console_print_internal_utf(con,x,y,w,h,TCOD_BKGND_NONE,TCOD_LEFT,TCOD_console_vsprint_utf(fmt,ap), true, true); va_end(ap); return ret; } #endif void TCOD_console_init_root(int w, int h, const char*title, bool fullscreen, TCOD_renderer_t renderer) { TCOD_IF(w > 0 && h > 0) { TCOD_console_data_t *con=(TCOD_console_data_t *)calloc(sizeof(TCOD_console_data_t),1); int i; con->w=w; con->h=h; TCOD_ctx.root=con; #ifdef TCOD_SDL2 TCOD_ctx.renderer=renderer; #endif for (i=0; i < TCOD_COLCTRL_NUMBER; i++) { color_control_fore[i]=TCOD_white; color_control_back[i]=TCOD_black; } TCOD_console_init((TCOD_console_t)con,title,fullscreen); } } static void TCOD_console_data_alloc(TCOD_console_data_t *dat) { dat->ch_array = (int *)calloc(sizeof(int), dat->w*dat->h); dat->fg_colors = TCOD_image_new(dat->w, dat->h); dat->bg_colors = TCOD_image_new(dat->w, dat->h); } bool TCOD_console_init(TCOD_console_t con,const char *title, bool fullscreen) { int i; TCOD_console_data_t *dat=con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT(dat != NULL) return false; dat->fore=TCOD_white; dat->back=TCOD_black; TCOD_console_data_alloc(dat); dat->bkgnd_flag=TCOD_BKGND_NONE; dat->alignment=TCOD_LEFT; for (i=0; i< dat->w*dat->h; i++) { dat->ch_array[i] = ' '; } if ( title ) { if (! TCOD_sys_init(dat, fullscreen) ) return false; TCOD_sys_set_window_title(title); } return true; } void TCOD_console_set_default_foreground(TCOD_console_t con,TCOD_color_t col) { TCOD_console_data_t *dat=con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT(dat != NULL) return; dat->fore=col; } void TCOD_console_set_default_background(TCOD_console_t con,TCOD_color_t col) { TCOD_console_data_t *dat=con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT(dat != NULL) return; dat->back=col; } TCOD_color_t TCOD_console_get_default_foreground(TCOD_console_t con) { TCOD_console_data_t *dat=con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT(dat != NULL) return TCOD_white; return dat->fore; } TCOD_color_t TCOD_console_get_default_background(TCOD_console_t con) { TCOD_console_data_t *dat=con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT(dat != NULL) return TCOD_black; return dat->back; } int TCOD_console_get_width(TCOD_console_t con) { TCOD_console_data_t *dat=con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT(dat != NULL) return 0; return dat->w; } int TCOD_console_get_height(TCOD_console_t con) { TCOD_console_data_t *dat=con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT(dat != NULL) return 0; return dat->h; } TCOD_image_t TCOD_console_get_foreground_color_image(TCOD_console_t con) { TCOD_console_data_t *dat = con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT(dat != NULL) return NULL; return dat->fg_colors; } TCOD_image_t TCOD_console_get_background_color_image(TCOD_console_t con) { TCOD_console_data_t *dat = con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT(dat != NULL) return NULL; return dat->bg_colors; } void TCOD_console_set_custom_font(const char *fontFile, int flags,int nb_char_horiz, int nb_char_vertic) { TCOD_sys_set_custom_font(fontFile, nb_char_horiz, nb_char_vertic, flags); } void TCOD_console_map_ascii_code_to_font(int asciiCode, int fontCharX, int fontCharY) { /* cannot change mapping before initRoot is called */ TCOD_IFNOT(TCOD_ctx.root != NULL) return; TCOD_sys_map_ascii_to_font(asciiCode, fontCharX, fontCharY); } void TCOD_console_map_ascii_codes_to_font(int asciiCode, int nbCodes, int fontCharX, int fontCharY) { int c; /* cannot change mapping before initRoot is called */ TCOD_IFNOT(TCOD_ctx.root != NULL) return; TCOD_IFNOT(asciiCode >= 0 && asciiCode+nbCodes <= TCOD_ctx.max_font_chars) return; for (c=asciiCode; c < asciiCode+nbCodes; c++ ) { TCOD_sys_map_ascii_to_font(c, fontCharX, fontCharY); fontCharX++; if ( fontCharX == TCOD_ctx.fontNbCharHoriz ) { fontCharX=0; fontCharY++; } } } void TCOD_console_map_string_to_font(const char *s, int fontCharX, int fontCharY) { TCOD_IFNOT(s != NULL) return; /* cannot change mapping before initRoot is called */ TCOD_IFNOT(TCOD_ctx.root != NULL) return; while (*s) { TCOD_console_map_ascii_code_to_font(*s, fontCharX, fontCharY); fontCharX++; if ( fontCharX == TCOD_ctx.fontNbCharHoriz ) { fontCharX=0; fontCharY++; } s++; } } bool TCOD_console_is_key_pressed(TCOD_keycode_t key) { return TCOD_sys_is_key_pressed(key); } void TCOD_console_set_key_color(TCOD_console_t con,TCOD_color_t col) { TCOD_console_data_t *dat=con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT(dat != NULL) return; TCOD_image_set_key_color(dat->bg_colors, col); } void TCOD_console_credits(void) { bool end=false; int x=TCOD_console_get_width(NULL)/2-6; int y=TCOD_console_get_height(NULL)/2; int fade=260; TCOD_sys_save_fps(); TCOD_sys_set_fps(25); while (!end ) { TCOD_key_t k; end=TCOD_console_credits_render(x,y,false); TCOD_sys_check_for_event(TCOD_EVENT_KEY_PRESS,&k,NULL); if ( fade == 260 && k.vk != TCODK_NONE ) { fade -= 10; } TCOD_console_flush(); if ( fade < 260 ) { fade -= 10; TCOD_console_set_fade(fade,TCOD_black); if ( fade == 0 ) end=true; } } TCOD_console_set_fade(255,TCOD_black); TCOD_sys_restore_fps(); } static bool init2=false; void TCOD_console_credits_reset(void) { init2=false; } bool TCOD_console_credits_render(int x, int y, bool alpha) { static char poweredby[128]; static float char_heat[128]; static int char_x[128]; static int char_y[128]; static bool init1=false; static int len,len1,cw=-1,ch=-1; static float xstr; static TCOD_color_t colmap[64]; static TCOD_color_t colmap_light[64]; static TCOD_noise_t noise; static TCOD_color_t colkeys[4] = { {255,255,204}, {255,204,0}, {255,102,0}, {102,153,255}, }; static TCOD_color_t colkeys_light[4] = { {255,255,204}, {128,128,77}, {51,51,31}, {0,0,0}, }; static int colpos[4]={ 0,21,42,63 }; static TCOD_image_t img=NULL; int i,xc,yc,xi,yi,j; static int left,right,top,bottom; float sparklex,sparkley,sparklerad,sparklerad2,noisex; /* mini particule system */ #define MAX_PARTICULES 50 static float pheat[MAX_PARTICULES]; static float px[MAX_PARTICULES],py[MAX_PARTICULES], pvx[MAX_PARTICULES],pvy[MAX_PARTICULES]; static int nbpart=0, firstpart=0; static float partDelay=0.1f; float elapsed=TCOD_sys_get_last_frame_length(); TCOD_color_t fbackup; /* backup fg color */ if (!init1) { /* initialize all static data, colormaps, ... */ TCOD_color_t col; TCOD_color_gen_map(colmap,4,colkeys,colpos); TCOD_color_gen_map(colmap_light,4,colkeys_light,colpos); sprintf(poweredby,"Powered by\n%s",version_string); noise=TCOD_noise_new(1,TCOD_NOISE_DEFAULT_HURST,TCOD_NOISE_DEFAULT_LACUNARITY,NULL); len=(int)strlen(poweredby); len1=11; /* sizeof "Powered by\n" */ left=MAX(x-4,0); top=MAX(y-4,0); col= TCOD_console_get_default_background(NULL); TCOD_console_set_default_background(NULL,TCOD_black); TCOD_console_set_default_background(NULL,col); init1=true; } if (!init2) { /* reset the credits vars ... */ int curx,cury; xstr=-4.0f; curx=x; cury=y; for (i=0; i < len ;i++) { char_heat[i]=-1; char_x[i]=curx; char_y[i]=cury; curx++; if ( poweredby[i] == '\n' ) { curx=x; cury++; } } nbpart=firstpart=0; init2=true; } if (TCOD_console_get_width(NULL) != cw || TCOD_console_get_height(NULL)!=ch) { /* console size has changed */ int width,height; cw=TCOD_console_get_width(NULL); ch=TCOD_console_get_height(NULL); right=MIN(x+len,cw-1); bottom=MIN(y+6,ch-1); width=right - left + 1; height=bottom - top + 1; if ( img ) TCOD_image_delete(img); img = TCOD_image_new(width*2,height*2); } fbackup=TCOD_console_get_default_foreground(NULL); if ( xstr < (float)len1 ) { sparklex=x+xstr; sparkley=(float)y; } else { sparklex=x-len1+xstr; sparkley=(float)y+1; } noisex=xstr*6; sparklerad=3.0f+2*TCOD_noise_get(noise,&noisex); if ( xstr >= len-1 ) sparklerad -= (xstr-len+1)*4.0f; else if ( xstr < 0.0f ) sparklerad += xstr*4.0f; else if ( poweredby[ (int)(xstr+0.5f) ] == ' ' || poweredby[ (int)(xstr+0.5f) ] == '\n' ) sparklerad/=2; sparklerad2=sparklerad*sparklerad*4; /* draw the light */ for (xc=left*2,xi=0; xc < (right+1)*2; xc++,xi++) { for (yc=top*2,yi=0; yc < (bottom+1)*2; yc++,yi++) { float dist=((xc-2*sparklex)*(xc-2*sparklex)+(yc-2*sparkley)*(yc-2*sparkley)); TCOD_color_t pixcol; if ( sparklerad >= 0.0f && dist < sparklerad2 ) { int colidx=63-(int)(63*(sparklerad2-dist)/sparklerad2) + TCOD_random_get_int(NULL,-10,10); colidx=CLAMP(0,63,colidx); pixcol=colmap_light[colidx]; } else { pixcol=TCOD_black; } if ( alpha ) { /* console cells have following flag values : 1 2 4 8 flag indicates which subcell uses foreground color */ static int asciiToFlag[] = { 1, /* TCOD_CHAR_SUBP_NW */ 2, /* TCOD_CHAR_SUBP_NE */ 3, /* TCOD_CHAR_SUBP_N */ 8, /* TCOD_CHAR_SUBP_SE */ 9, /* TCOD_CHAR_SUBP_DIAG */ 10, /* TCOD_CHAR_SUBP_E */ 4, /* TCOD_CHAR_SUBP_SW */ }; int conc= TCOD_console_get_char(NULL,xc/2,yc/2); TCOD_color_t bk=TCOD_console_get_char_background(NULL,xc/2,yc/2); if ( conc >= TCOD_CHAR_SUBP_NW && conc <= TCOD_CHAR_SUBP_SW ) { /* merge two subcell chars... get the flag for the existing cell on root console */ int bkflag=asciiToFlag[conc - TCOD_CHAR_SUBP_NW ]; int xflag = (xc & 1); int yflag = (yc & 1); /* get the flag for the current subcell */ int credflag = (1+3*yflag) * (xflag+1); if ( (credflag & bkflag) != 0 ) { /* the color for this subcell on root console is foreground, not background */ bk = TCOD_console_get_char_foreground(NULL,xc/2,yc/2); } } pixcol.r = MIN(255,(int)(bk.r)+pixcol.r); pixcol.g = MIN(255,(int)(bk.g)+pixcol.g); pixcol.b = MIN(255,(int)(bk.b)+pixcol.b); } TCOD_image_put_pixel(img,xi,yi,pixcol); } } /* draw and update the particules */ j=nbpart;i=firstpart; while (j > 0) { int colidx=(int)(64*(1.0f-pheat[i])); TCOD_color_t col; colidx=MIN(63,colidx); col=colmap[colidx]; if ( (int)py[i]< (bottom-top+1)*2 ) { int ipx = (int)px[i]; int ipy = (int)py[i]; float fpx = px[i]-ipx; float fpy = py[i]-ipy; TCOD_color_t col2=TCOD_image_get_pixel(img,ipx,ipy); col2=TCOD_color_lerp(col,col2,0.5f*(fpx+fpy)); TCOD_image_put_pixel(img,ipx,ipy,col2); col2=TCOD_image_get_pixel(img,ipx+1,ipy); col2=TCOD_color_lerp(col2,col,fpx); TCOD_image_put_pixel(img,ipx+1,ipy,col2); col2=TCOD_image_get_pixel(img,ipx,ipy+1); col2=TCOD_color_lerp(col2,col,fpy); TCOD_image_put_pixel(img,ipx,ipy+1,col2); } else pvy[i]=-pvy[i] * 0.5f; pvx[i] *= (1.0f-elapsed); pvy[i] += (1.0f-pheat[i])*elapsed*300.0f; px[i] += pvx[i]*elapsed; py[i] += pvy[i]*elapsed; pheat[i] -= elapsed*0.3f; if ( pheat[i] < 0.0f ) { firstpart = (firstpart+1)%MAX_PARTICULES; nbpart--; } i = (i+1)%MAX_PARTICULES; j--; } partDelay -= elapsed; if ( partDelay < 0.0f && nbpart < MAX_PARTICULES && sparklerad > 2.0f ) { /* fire a new particule */ int lastpart = firstpart; int nb=nbpart; while (nb > 0 ) { lastpart = ( lastpart + 1 )%MAX_PARTICULES; nb--; } nbpart++; px[lastpart] = 2*(sparklex-left); py[lastpart] = 2*(sparkley-top)+2; pvx[lastpart] = TCOD_random_get_float(NULL,-5.0f,5.0f); pvy[lastpart] = TCOD_random_get_float(NULL,-0.5f, -15.0f); pheat[lastpart] = 1.0f; partDelay += 0.1f; } TCOD_image_blit_2x(img,NULL,left,top,0,0,-1,-1); /* draw the text */ for (i=0; i < len ;i++) { if ( char_heat[i] >= 0.0f && poweredby[i]!='\n') { int colidx=(int)(64*char_heat[i]); TCOD_color_t col; colidx=MIN(63,colidx); col=colmap[colidx]; if ( xstr >= len ) { float coef=(xstr-len)/len; if ( alpha ) { TCOD_color_t fore=TCOD_console_get_char_background(NULL,char_x[i],char_y[i]); int r=(int)(coef*fore.r + (1.0f-coef)*col.r); int g=(int)(coef*fore.g + (1.0f-coef)*col.g); int b=(int)(coef*fore.b + (1.0f-coef)*col.b); col.r = CLAMP(0,255,r); col.g = CLAMP(0,255,g); col.b = CLAMP(0,255,b); TCOD_console_set_char_foreground(NULL,char_x[i],char_y[i],col); } else { col=TCOD_color_lerp(col,TCOD_black,coef); } } TCOD_console_set_char(NULL,char_x[i],char_y[i],poweredby[i]); TCOD_console_set_char_foreground(NULL,char_x[i],char_y[i],col); } } /* update letters heat */ xstr += elapsed * 4; for (i=0; i < (int)(xstr+0.5f); i++) { char_heat[i]=(xstr-i)/(len/2); } /* restore fg color */ TCOD_console_set_default_foreground(NULL,fbackup); if ( xstr <= 2*len ) return false; init2=false; return true; } static void TCOD_console_read_asc(TCOD_console_t con,FILE *f,int width, int height, float version) { int x,y; TCOD_console_data_t *dat=con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_IFNOT(dat != NULL) return; while(fgetc(f) != '#'); for(x = 0; x < width; x++) { for(y = 0; y < height; y++) { TCOD_color_t fore,back; int c = fgetc(f); fore.r = fgetc(f); fore.g = fgetc(f); fore.b = fgetc(f); back.r = fgetc(f); back.g = fgetc(f); back.b = fgetc(f); /* skip solid/walkable info */ if ( version >= 0.3f ) { fgetc(f); fgetc(f); } TCOD_console_put_char_ex(con,x,y,c,fore,back); } } fclose(f); } static void TCOD_console_read_apf(TCOD_console_t con,FILE *f,int width, int height, float version) { } static int string_ends_with(const char *str, const char *suffix) { size_t str_len = strlen(str); size_t suffix_len = strlen(suffix); return (str_len >= suffix_len) && (0 == strcmp(str + (str_len-suffix_len), suffix)); } TCOD_console_t TCOD_console_from_file(const char *filename) { float version; int width,height; TCOD_console_t con; FILE *f; TCOD_IFNOT( filename != NULL ) { return NULL; } if (string_ends_with(filename, ".xp")) { return TCOD_console_from_xp(filename); } f=fopen(filename,"rb"); TCOD_IFNOT( f!=NULL ) { return NULL; } if (fscanf(f, "ASCII-Paint v%g", &version) != 1 ) { fclose(f); return NULL; } if (fscanf(f, "%i %i", &width, &height) != 2 ) { fclose(f); return NULL; } TCOD_IFNOT ( width > 0 && height > 0) { fclose(f); return NULL; } con=TCOD_console_new(width,height); if (string_ends_with(filename, ".asc")) { TCOD_console_read_asc(con,f,width,height,version); } else { TCOD_console_read_apf(con,f,width,height,version); } return con; } bool TCOD_console_load_asc(TCOD_console_t pcon, const char *filename) { float version; int width,height; FILE *f; TCOD_console_data_t *con=pcon ? (TCOD_console_data_t *)pcon : TCOD_ctx.root; TCOD_IFNOT(con != NULL) return false; TCOD_IFNOT( filename != NULL ) { return false; } f=fopen(filename,"rb"); TCOD_IFNOT( f!=NULL ) { return false; } if (fscanf(f, "ASCII-Paint v%g", &version) != 1 ) { fclose(f); return false; } if (fscanf(f, "%i %i", &width, &height) != 2 ) { fclose(f); return false; } TCOD_IFNOT ( width > 0 && height > 0) { fclose(f); return false; } if ( con->w != width || con->h != height ) { /* resize console */ TCOD_console_data_free(con); con->w = width; con->h = height; TCOD_console_data_alloc(con); } TCOD_console_read_asc(con,f,width,height,version); return true; } bool TCOD_console_save_asc(TCOD_console_t pcon, const char *filename) { static float version = 0.3f; FILE *f; int x,y; TCOD_console_data_t *con=pcon ? (TCOD_console_data_t *)pcon : TCOD_ctx.root; TCOD_IFNOT(con != NULL) return false; TCOD_IFNOT( filename != NULL ) { return false; } TCOD_IFNOT(con->w > 0 && con->h > 0) return false; f=fopen(filename,"wb"); TCOD_IFNOT( f != NULL ) return false; fprintf(f, "ASCII-Paint v%g\n", version); fprintf(f, "%i %i\n", con->w, con->h); fputc('#', f); for(x = 0; x < con->w; x++) { for(y = 0; y < con->h; y++) { TCOD_color_t fore,back; int c=TCOD_console_get_char(con,x,y); fore=TCOD_console_get_char_foreground(con,x,y); back=TCOD_console_get_char_background(con,x,y); fputc(c, f); fputc(fore.r,f); fputc(fore.g,f); fputc(fore.b,f); fputc(back.r,f); fputc(back.g,f); fputc(back.b,f); fputc(0,f); /* solid */ fputc(1,f); /* walkable */ } } fclose(f); return true; } static bool hasDetectedBigEndianness = false; static bool isBigEndian; void detectBigEndianness(void) { if (!hasDetectedBigEndianness){ uint32_t Value32; uint8_t *VPtr = (uint8_t *)&Value32; VPtr[0] = VPtr[1] = VPtr[2] = 0; VPtr[3] = 1; if(Value32 == 1) isBigEndian = true; else isBigEndian = false; hasDetectedBigEndianness = true; } } uint16_t bswap16(uint16_t s){ uint8_t* ps = (uint8_t*)&s; uint16_t res; uint8_t* pres = (uint8_t*)&res; pres[0] = ps[1]; pres[1] = ps[0]; return res; } uint32_t bswap32(uint32_t s){ uint8_t *ps=(uint8_t *)(&s); uint32_t res; uint8_t *pres=(uint8_t *)&res; pres[0]=ps[3]; pres[1]=ps[2]; pres[2]=ps[1]; pres[3]=ps[0]; return res; } uint16_t l16(uint16_t s){ if (isBigEndian) return bswap16(s); else return s; } uint32_t l32(uint32_t s){ if (isBigEndian) return bswap32(s); else return s; } /* fix the endianness */ void fix16(uint16_t* u){ *u = l16(*u); } void fix32(uint32_t* u){ *u = l32(*u); } /************ RIFF helpers */ uint32_t fourCC(const char* c){ return (*(uint32_t*)c); } /* checks if u equals str */ bool fourCCequals(uint32_t u, const char* str){ return fourCC(str)==u; } void fromFourCC(uint32_t u, char*s){ const char* c = (const char*)(&u); s[0]=c[0]; s[1]=c[1]; s[2]=c[2]; s[3]=c[3]; s[4]=0; } void put8(uint8_t d, FILE* fp){ fwrite(&d,1,1,fp); } void put16(uint16_t d, FILE* fp){ fwrite(&d,2,1,fp); } void put32(uint32_t d, FILE* fp){ fwrite(&d,4,1,fp); } void putFourCC(const char* c, FILE* fp){ put32(fourCC(c),fp); } void putData(void* what, int length, FILE* fp){ fwrite(what,length,1,fp); } bool get8(uint8_t* u, FILE* fp){ return 1==fread((void*)u, sizeof(uint8_t),1,fp); } bool get16(uint16_t* u, FILE* fp){ return 1==fread((void*)u, sizeof(uint16_t),1,fp); } bool get32(uint32_t* u, FILE* fp){ return 1==fread((void*)u, sizeof(uint32_t),1,fp); } bool getData(void* u, size_t sz, FILE* fp){ return 1==fread(u, sz,1,fp); } /********* APF RIFF structures */ typedef struct { uint32_t show_grid; uint32_t grid_width; uint32_t grid_height; } SettingsDataV1; #define FILTER_TYPE_UNCOMPRESSED 0 #define FORMAT_TYPE_CRGBRGB 0 typedef struct { uint32_t width; uint32_t height; uint32_t filter; uint32_t format; } ImageDetailsV1; /* Layers */ typedef struct { uint32_t name; uint32_t mode; uint32_t index; uint32_t dataSize; } LayerV1 ; typedef struct { uint32_t name; uint32_t mode; uint32_t fgalpha; uint32_t bgalpha; uint32_t visible; uint32_t index; uint32_t dataSize; } LayerV2; /* fix the endianness */ void fixSettings(SettingsDataV1* s){ fix32(&s->show_grid); fix32(&s->grid_width); fix32(&s->grid_height); } void fixImage(ImageDetailsV1* v){ fix32(&v->width); fix32(&v->height); fix32(&v->filter); fix32(&v->format); } void fixLayerv1(LayerV1* l){ fix32(&l->mode); fix32(&l->index); fix32(&l->dataSize); } void fixLayerv2(LayerV2* l){ fix32(&l->mode); fix32(&l->fgalpha); fix32(&l->bgalpha); fix32(&l->visible); fix32(&l->index); fix32(&l->dataSize); } /*********** ApfFile */ bool TCOD_console_save_apf(TCOD_console_t pcon, const char *filename) { TCOD_console_data_t *con=pcon ? (TCOD_console_data_t *)pcon : TCOD_ctx.root; FILE* fp ; TCOD_IFNOT(con != NULL) return false; detectBigEndianness(); fp = fopen(filename, "wb"); if(fp == NULL) { return false; } else { int x,y; uint32_t riffSize = 0; uint32_t imgDetailsSize ; SettingsDataV1 settingsData; ImageDetailsV1 imgData; fpos_t posRiffSize; uint32_t settingsSz ; uint32_t layerImageSize ; uint32_t layerChunkSize ; /* riff header*/ putFourCC("RIFF",fp); fgetpos(fp,&posRiffSize); put32(0,fp); /* APF_ header */ putFourCC("apf ",fp); riffSize += 4; /* settings */ settingsData.show_grid = 0; settingsData.grid_width = 8; settingsData.grid_height = 8; settingsSz = sizeof(uint32_t) + sizeof settingsData; putFourCC("sett",fp); put32(l32(settingsSz),fp); put32(l32(1),fp); putData((void*)&settingsData,sizeof settingsData,fp); if (settingsSz&1){ put8(0,fp); riffSize++; } riffSize += 4+4+settingsSz; /* image details */ imgData.width = con->w; imgData.height = con->h; imgData.filter = 0; imgData.format = 0; imgDetailsSize = sizeof(uint32_t) + sizeof imgData; putFourCC("imgd",fp); put32(l32(imgDetailsSize),fp); put32(l32(1),fp); putData((void*)&imgData,sizeof imgData,fp); if (imgDetailsSize&1){ put8(0,fp); riffSize++; } riffSize += 4+4+imgDetailsSize; /* now write the layers as a RIFF list the first layer is the lowest layer Assume imgData filter = uncompressed, and imgData format = CRGB */ layerImageSize = imgData.width*imgData.height*7; layerChunkSize = sizeof(uint32_t) /* version */ + sizeof(LayerV2) /* header */ + layerImageSize; /* data */ putFourCC("layr",fp); /* layer */ put32(l32(layerChunkSize),fp); /* VERSION -> */ put32(l32(2),fp); /* Data */ putFourCC("LAY0",fp); put32(l32(0),fp); put32(l32(255),fp); put32(l32(255),fp); put32(l32(1),fp); put32(l32(0),fp); put32(l32(layerImageSize),fp); /* now write out the data */ for(x = 0; x < con->w; x++) { for(y = 0; y < con->h; y++) { TCOD_color_t fore,back; int c=TCOD_console_get_char(con,x,y); fore=TCOD_console_get_char_foreground(con,x,y); back=TCOD_console_get_char_background(con,x,y); put8(c, fp); put8(fore.r,fp); put8(fore.g,fp); put8(fore.b,fp); put8(back.r,fp); put8(back.g,fp); put8(back.b,fp); } } if (layerChunkSize&1){ put8(0,fp); /* padding bit */ riffSize++; } riffSize += 2*sizeof(uint32_t)+layerChunkSize; fsetpos(fp,&posRiffSize); put32(l32(riffSize),fp); } fclose(fp); return true; } typedef struct { LayerV1 headerv1; LayerV2 headerv2; uint8_t* data; /* dynamically allocated */ } LayerData; typedef struct { ImageDetailsV1 details; SettingsDataV1 settings; LayerData layer; } Data; bool TCOD_console_load_apf(TCOD_console_t pcon, const char *filename) { uint32_t sett = fourCC("sett"); uint32_t imgd = fourCC("imgd"); /* uint32_t LIST = fourCC("LIST"); uint32_t LAYR = fourCC("LAYR"); */ uint32_t layr = fourCC("layr"); FILE* fp ; Data data; TCOD_console_data_t *con=pcon ? (TCOD_console_data_t *)pcon : TCOD_ctx.root; TCOD_IFNOT(con != NULL) return false; detectBigEndianness(); data.details.width = 1; data.details.height = 1; data.details.filter = 0; data.details.format = 0; data.settings.show_grid = true; data.settings.grid_width = 10; data.settings.grid_height = 10; #define ERR(x) {printf("Error: %s\n. Aborting operation.",x); return false;} #define ERR_NEWER(x) {printf("Error: It looks like this file was made with a newer version of Ascii-Paint\n. In particular the %s field. Aborting operation.",x); return false;} fp = fopen(filename, "rb"); if(fp == NULL) { printf("The file %s could not be loaded.\n", filename); return false; } else { /* read the header */ uint32_t riff; uint32_t riffSize; int index = 0; int x,y; uint8_t *imgData; bool keepGoing = true; if (! get32(&riff,fp) || ! fourCCequals(riff,"RIFF")){ ERR("File doesn't have a RIFF header"); } if (!get32(&riffSize,fp)) ERR("No RIFF size field!"); fix32(&riffSize); while(keepGoing && fp){ /* for each subfield, try to find the APF_ field */ uint32_t apf; if (! get32(&apf,fp)) break; if (fourCCequals(apf,"apf ") || fourCCequals(apf,"APF ")){ /* Process APF segment */ while(keepGoing && fp){ uint32_t seg; if (! get32(&seg,fp)){ keepGoing = false; break; } else { if (seg==sett){ /* size */ uint32_t sz; uint32_t ver; SettingsDataV1 settingsData; get32(&sz,fp); fix32(&sz); /* version */ get32(&ver,fp); fix32(&ver); if (ver!=1) ERR_NEWER("settings"); /* ver must be 1 */ if (! getData((void*)&settingsData,sizeof settingsData,fp)) ERR("Can't read settings."); data.settings = settingsData; fixSettings(&data.settings); } else if (seg==imgd){ /* sz */ uint32_t sz; uint32_t ver; ImageDetailsV1 dets; get32(&sz,fp); fix32(&sz); /* version */ get32(&ver,fp); fix32(&ver); if (ver!=1) ERR_NEWER("image details"); /* ver must be 1 */ if (! getData((void*)&dets, sizeof dets, fp)) ERR("Can't read image details."); data.details = dets; fixImage(&data.details); /* get canvas ready */ TCOD_IFNOT ( data.details.width > 0 && data.details.height > 0) { fclose(fp); return false; } if ( con->w != data.details.width || con->h != data.details.height ) { /* resize console */ TCOD_console_data_free(con); con->w = data.details.width; con->h = data.details.height; TCOD_console_data_alloc(con); } } else if (seg==layr){ uint32_t sz; uint32_t ver; get32(&sz,fp); fix32(&sz); /* version */ get32(&ver,fp); fix32(&ver); if (ver>2) ERR_NEWER("layer spec"); if (ver==1){ if (! getData((void*)&data.layer.headerv1, sizeof( LayerV1 ), fp)) ERR("Can't read layer header."); fixLayerv1(&data.layer.headerv1); /* Read in the data chunk*/ data.layer.data = (uint8_t*)malloc(sizeof(uint8_t)*data.layer.headerv1.dataSize); getData((void*) data.layer.data, data.layer.headerv1.dataSize, fp); } else if (ver==2){ if (! getData((void*)&data.layer.headerv2, sizeof( LayerV2 ), fp)) ERR("Can't read layer header."); fixLayerv2(&data.layer.headerv2); /* Read in the data chunk */ data.layer.data = (uint8_t*)malloc(sizeof(uint8_t)*data.layer.headerv2.dataSize); getData((void*) data.layer.data, data.layer.headerv2.dataSize, fp); } } else { /* skip unknown segment */ uint32_t sz; get32(&sz,fp); fix32(&sz); fseek(fp,sz,SEEK_CUR); } } } /* we're done! */ keepGoing = false; } else { /* skip this segment */ uint32_t sz; get32(&sz,fp); fseek(fp,sz,SEEK_CUR); } } imgData = data.layer.data; for(x = 0; x < con->w; x++) { for(y = 0; y < con->h; y++) { TCOD_color_t fore,back; int c = (unsigned char)(imgData[index++]); fore.r = (uint8_t)(imgData[index++]); fore.g = (uint8_t)(imgData[index++]); fore.b = (uint8_t)(imgData[index++]); back.r = (uint8_t)(imgData[index++]); back.g = (uint8_t)(imgData[index++]); back.b = (uint8_t)(imgData[index++]); TCOD_console_put_char_ex(con,x,y,c,fore,back); } } free (data.layer.data); } fclose(fp); return true; } /* bool ApfFile::Load(std::string filename){ detectBigEndianness(); uint32_t sett = fourCC("sett"); uint32_t imgd = fourCC("imgd"); uint32_t LIST = fourCC("LIST"); uint32_t LAYR = fourCC("LAYR"); uint32_t layr = fourCC("layr"); Data data; // File data data.details.width = 1; data.details.height = 1; data.details.filter = FILTER_TYPE_UNCOMPRESSED; data.details.format = FORMAT_TYPE_CRGBRGB; data.settings.show_grid = true; data.settings.grid_width = 10; data.settings.grid_height = 10; data.currentLayer = NULL; #define ERR(x) {printf("Error: %s\n. Aborting operation.",x); return false;} #define ERR_NEWER(x) {printf("Error: It looks like this file was made with a newer version of Ascii-Paint\n. In particular the %s field. Aborting operation.",x); return false;} FILE* fp = fopen(filename.c_str(), "rb"); if(fp == NULL) { printf("The file %s could not be loaded.\n", filename.c_str()); return false; } else { // read the header uint32_t riff; if (not get32(&riff,fp) or not fourCCequals(riff,"RIFF")){ ERR("File doesn't have a RIFF header"); } // else uint32_t riffSize; if (!get32(&riffSize,fp)) ERR("No RIFF size field!"); fix(&riffSize); bool keepGoing = true; while(keepGoing and fp){ // for each subfield, try to find the APF_ field uint32_t apf; if (not get32(&apf,fp)) break; if (fourCCequals(apf,"apf ") or fourCCequals(apf,"APF ")){ // Process APF segment while(keepGoing and fp){ uint32_t seg; if (not get32(&seg,fp)){ keepGoing = false; break; } else { if (seg==sett){ // size uint32_t sz; get32(&sz,fp); fix(&sz); // version uint32_t ver; get32(&ver,fp); fix(&ver); if (ver!=1) ERR_NEWER("settings"); // ver must be 1 SettingsDataV1 settingsData; if (not getData((void*)&settingsData,sizeof settingsData,fp)) ERR("Can't read settings."); data.settings = settingsData; fix(&data.settings); // Change app settings app->setGridDimensions(data.settings.grid_width,data.settings.grid_height); app->setShowGrid(data.settings.show_grid==1); } else if (seg==imgd){ // sz uint32_t sz; get32(&sz,fp); fix(&sz); // version uint32_t ver; get32(&ver,fp); fix(&ver); if (ver!=1) ERR_NEWER("image details"); // ver must be 1 ImageDetailsV1 dets; if (not getData((void*)&dets, sizeof dets, fp)) ERR("Can't read image details."); data.details = dets; fix(&data.details); // get canvas ready app->canvasWidth = data.details.width; app->canvasHeight = data.details.height; app->initCanvas(); // delete new layer app->deleteLayer(app->getCurrentLayer()->name); } else if (seg==layr){ // printf("Found a layer\n"); // sz uint32_t sz; get32(&sz,fp); fix(&sz); // version uint32_t ver; get32(&ver,fp); fix(&ver); if (ver>2) ERR_NEWER("layer spec"); if (ver==1){ LayerV1 layerHeader; if (not getData((void*)&layerHeader, sizeof layerHeader, fp)) ERR("Can't read layer header."); fix(&layerHeader); // creat new layer data LayerData* ld = new LayerData; ld->header = layerHeader; // already fix'd ld->data = new uint8[ld->header.dataSize]; // Read in the data chunk getData((void*) ld->data, ld->header.dataSize, fp); // push layer onto the list data.currentLayer = ld; data.layers.push(ld); } else if (ver==2){ LayerV2 layerHeader; if (not getData((void*)&layerHeader, sizeof layerHeader, fp)) ERR("Can't read layer header."); fix(&layerHeader); // creat new layer data LayerData* ld = new LayerData; ld->header = layerHeader; // already fix'd ld->data = new uint8[ld->header.dataSize]; // Read in the data chunk getData((void*) ld->data, ld->header.dataSize, fp); // push layer onto the list data.currentLayer = ld; data.layers.push(ld); } } else { // skip unknown segment uint32_t sz; get32(&sz,fp); fix(&sz); fseek(fp,sz,SEEK_CUR); } } } // we're done! keepGoing = false; } else { // skip this segment uint32_t sz; get32(&sz,fp); fseek(fp,sz,SEEK_CUR); } } // finally, copy the layers into the current document for(int i=0;iaddNewLayer(); // Parse layer header l->name = fromFourCC(ld->header.name); l->fgalpha = ld->header.fgalpha; l->bgalpha = ld->header.bgalpha; l->visible = (ld->header.visible==1); // l->compositingMode = // Copy data into currently selected canvas uint8_t* imgData = ld->data; CanvasImage *img = new CanvasImage; // Write the brush data for every brush in the image int index = 0; for(int x = 0; x < app->canvasWidth; x++) { for(int y = 0; y < app->canvasHeight; y++) { Brush b; b.symbol = (unsigned char)(imgData[index++]); b.fore.r = (uint8_t)(imgData[index++]); b.fore.g = (uint8_t)(imgData[index++]); b.fore.b = (uint8_t)(imgData[index++]); b.back.r = (uint8_t)(imgData[index++]); b.back.g = (uint8_t)(imgData[index++]); b.back.b = (uint8_t)(imgData[index++]); b.solid = true; // deprecated b.walkable = true; // deprecated img->push_back(b); } } app->setCanvasImage(*img); delete img; } // then free all the temporary layer data for(int i=0;idata; delete data.layers.get(i); } // and update the layer widget app->gui->layerWidget->regenerateLayerList(); } fclose(fp); return true; } */ #endif /* TCOD_CONSOLE_SUPPORT */ libtcod-1.6.4+dfsg/src/console_rexpaint.c000066400000000000000000000302751321276576200204120ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #ifdef TCOD_CONSOLE_SUPPORT #include /* Needed only for TCOD_fatal */ #include #include #include /* Confirm that the current types are the same as what this code expects. */ #if UINT_MAX != 0xffffffff #error int type must be 32-bit! #endif #ifdef TCOD_SDL2 #include #if SDL_BYTEORDER != SDL_LIL_ENDIAN #error byte-order must be little endian! #endif #endif struct RexPaintHeader { int version; int layer_count; }; struct RexPaintLayerChunk { int width; int height; }; struct RexPaintTile { int ch; TCOD_color_t fg; TCOD_color_t bg; }; /* Read data from a gz file, returns 0 on success, or -1 on any error. */ static int load_gz_confirm(gzFile gz_file, void *data, size_t length) { if (gzread(gz_file, data, (int)length) != length) { return -1; } return 0; } static int load_header(gzFile gz_file, struct RexPaintHeader *xp_header) { return load_gz_confirm(gz_file, xp_header, sizeof(xp_header[0])); } static int load_layer(gzFile gz_file, struct RexPaintLayerChunk *xp_layer) { return load_gz_confirm(gz_file, xp_layer, sizeof(xp_layer[0])); } /* Read a single REXPaint tile, return 0 on success, or -1 on error. */ static int load_tile(gzFile gz_file, struct RexPaintTile *tile) { return ( load_gz_confirm(gz_file, &tile->ch, sizeof(tile->ch)) || load_gz_confirm(gz_file, &tile->fg, sizeof(tile->fg)) || load_gz_confirm(gz_file, &tile->bg, sizeof(tile->bg)) ); } /* Read a layer of REXPaint tiles onto a console. If transparent is true, then follow REXPaint's rules for transparency. */ static int load_tiles( gzFile gz_file, TCOD_console_t console, int transparent) { int x, y; const int width = TCOD_console_get_width(console); const int height = TCOD_console_get_height(console); /* REXPaint tiles are in column-major order. */ for (x = 0; x < width; ++x) { for (y = 0; y < height; ++y) { struct RexPaintTile tile; if (load_tile(gz_file, &tile)) { return -1; } /* REXPaint uses a magic pink background to mark transparency. */ if (transparent && tile.bg.r == 0xff && tile.bg.g == 0x00 && tile.bg.b == 0xff) { continue; } TCOD_console_set_char(console, x, y, tile.ch); TCOD_console_set_char_foreground(console, x, y, tile.fg); TCOD_console_set_char_background(console, x, y, tile.bg, TCOD_BKGND_SET); } } return 0; } /* Return the next REXPaint layer as a console. After reading the header you could just keep calling this function until it returns NULL. */ static TCOD_console_t load_console(gzFile gz_file) { struct RexPaintLayerChunk xp_layer; TCOD_console_t console; if (load_layer(gz_file, &xp_layer)) { return NULL; } console = TCOD_console_new(xp_layer.width, xp_layer.height); if (!console) { return NULL; } if (load_tiles(gz_file, console, 0)) { TCOD_console_delete(console); return NULL; } return console; } /* Load all the contents of a REXPaint file into a list of consoles. */ static TCOD_list_t load_consoleList(gzFile gz_file) { struct RexPaintHeader xp_header; TCOD_list_t console_list; int i; if (load_header(gz_file, &xp_header)) { return NULL; } console_list = TCOD_list_allocate(xp_header.layer_count); if (!console_list) { return NULL; } for (i = 0; i < xp_header.layer_count; ++i) { TCOD_console_t console = load_console(gz_file); if (!console) { /* There was an issue then delete everything so far and return NULL */ while (!TCOD_list_is_empty(console_list)) { TCOD_console_delete(TCOD_list_pop(console_list)); } TCOD_list_delete(console_list); return NULL; } TCOD_list_push(console_list, console); } return console_list; } /* Convert a list of consoles into a single console, deleting the list. Follows REXPaint's rules for transparency. */ static TCOD_console_t combine_console_list(TCOD_list_t console_list) { TCOD_console_t main_console; if (!console_list) { return NULL; } /* Reverse the list so that elements will be dequeued. */ TCOD_list_reverse(console_list); main_console = TCOD_list_pop(console_list); while (!TCOD_list_is_empty(console_list)) { TCOD_console_t console = TCOD_list_pop(console_list); /* Set key color to {255, 0, 255} before blit. */ TCOD_console_set_key_color(console, TCOD_fuchsia); /* This blit may fail if the consoles do not match shapes. */ TCOD_console_blit(console, 0, 0, 0, 0, main_console, 0, 0, 1.0f, 1.0f); TCOD_console_delete(console); } TCOD_list_delete(console_list); return main_console; } /** * \brief Return a list of consoles from a REXPaint file. * * \param [in] A path to the REXPaint file. * \return Returns a TCOD_list_t of TCOD_console_t objects. Or NULL on an * error. You will need to delete this list and each console individually. * * \details This function can load a REXPaint file with variable layer shapes, * which would cause issues for a function like TCOD_console_list_from_xp. */ TCOD_list_t TCOD_console_list_from_xp(const char *filename) { int z_errno = Z_ERRNO; TCOD_list_t console_list; gzFile gz_file = gzopen(filename, "rb"); if (!gz_file) { TCOD_fatal("Could not open file: '%s'", filename); return NULL; } console_list = load_consoleList(gz_file); if (!console_list){ TCOD_fatal("Error parsing '%s'\n%s", filename, gzerror(gz_file, &z_errno)); /* Could fall-through here and return NULL. */ } gzclose(gz_file); return console_list; } /** * \brief Return a new console loaded from a REXPaint ``.xp`` file. * * \param [in] filename A path to the REXPaint file. * \param [in] layer The specific layer to return, or ``0`` to return a * console with all layers overlaid using REXPaint's rules for transparency. * \return A new TCOD_console_t object. New consoles will need * to be deleted with a call to :any:`TCOD_console_delete`. * Returns NULL on an error. * * \details REXPaint gives special treatment to tiles with a magic pink * ``{255, 0, 255}`` background color. You can processes this color * manually or set :any:`TCOD_console_set_key_color` to `TCOD_fuchsia`. */ TCOD_console_t TCOD_console_from_xp(const char *filename) { return combine_console_list(TCOD_console_list_from_xp(filename)); } /** * \brief Update a console from a REXPaint ``.xp`` file. * * \param [out] con A console instance to update from the REXPaint file. * \param [in] filename A path to the REXPaint file. * * \details REXPaint gives special treatment to tiles with a magic pink * ``{255, 0, 255}`` background color. You can processes this color * manually or set :any:`TCOD_console_set_key_color` to `TCOD_fuchsia`. */ bool TCOD_console_load_xp(TCOD_console_t con, const char *filename) { TCOD_console_t xp_console = TCOD_console_from_xp(filename); if (!xp_console) { return false; } if (TCOD_console_get_width(con) != TCOD_console_get_width(xp_console) || TCOD_console_get_height(con) != TCOD_console_get_height(xp_console)) { TCOD_console_delete(xp_console); return false; } TCOD_console_blit(xp_console, 0, 0, 0, 0, con, 0, 0, 1.0f, 1.0f); TCOD_console_delete(xp_console); return true; } static int write_header(gzFile gz_file, struct RexPaintHeader *xp_header) { if (!gzwrite(gz_file, xp_header, sizeof(xp_header[0]))) { return -1; } return 0; } static int write_layer(gzFile gz_file, struct RexPaintLayerChunk *xp_layer) { if (!gzwrite(gz_file, xp_layer, sizeof(xp_layer[0]))) { return -1; } return 0; } static int write_tile(gzFile gz_file, struct RexPaintTile *tile) { if (!gzwrite(gz_file, &tile->ch, sizeof(tile->ch)) || !gzwrite(gz_file, &tile->fg, sizeof(tile->fg)) || !gzwrite(gz_file, &tile->bg, sizeof(tile->bg))) { return -1; } return 0; } static int write_console(gzFile gz_file, TCOD_console_t console) { int x, y; struct RexPaintLayerChunk xp_layer; xp_layer.width = TCOD_console_get_width(console); xp_layer.height = TCOD_console_get_height(console); if (write_layer(gz_file, &xp_layer)) { return -1; /* error writing layer */ } /* Write console data out in column-major order. */ for (x = 0; x < xp_layer.width; ++x) { for (y = 0; y < xp_layer.height; ++y) { struct RexPaintTile tile; tile.ch = TCOD_console_get_char(console, x, y); tile.fg = TCOD_console_get_char_foreground(console, x, y); tile.bg = TCOD_console_get_char_background(console, x, y); if (write_tile(gz_file, &tile)) { return -1; /* error writing tile data */ } } } return 0; } /** * \brief Save a console as a REXPaint ``.xp`` file. * * \param [in] con The console instance to save. * \param [in] filename The filepath to save to. * \param [in] compress_level A zlib compression level, from 0 to 9. * 1=fast, 6=balanced, 9=slowest, 0=uncompressed. * \return ``true`` when the file is saved succesfully, or ``false`` when an * issue is detected. * * \details REXPaint has enough fidelity to make a 1:1 copy of a libtcod * console. */ bool TCOD_console_save_xp( TCOD_console_t con, const char *filename, int compress_level) { struct RexPaintHeader xp_header; gzFile gz_file = gzopen(filename, "wb"); if (!gz_file) { return false; /* could not open file */ } gzsetparams(gz_file, compress_level, Z_DEFAULT_STRATEGY); xp_header.version = -1; /* REXPaint uses this version. */ xp_header.layer_count = 1; if (write_header(gz_file, &xp_header) || write_console(gz_file, con)) { gzclose(gz_file); return false; /* error writing data */ } if (gzclose(gz_file)) { return false; /* error writing to file */ } return true; } /** * \brief Save a list of consoles to a REXPaint file. * * \param [in] A TCOD_list_t of TCOD_console_t objects. * \param [in] Path to save to. * \param [in] zlib compression level. * \return true on success, false on a failure such as not being able to write * to the path provided. * * \details The REXPaint tool can only work on files with up to 4 layers where * all layers are the same size. * * This function can save any number of layers with multiple different sizes, * these files can be loaded without issues as long you use * :any:`TCOD_console_list_from_xp` for loading. */ bool TCOD_console_list_save_xp( TCOD_list_t console_list, const char *filename, int compress_level) { int i; struct RexPaintHeader xp_header; gzFile gz_file = gzopen(filename, "wb"); if (!gz_file) { return false; /* could not open file */ } gzsetparams(gz_file, compress_level, Z_DEFAULT_STRATEGY); xp_header.version = -1; xp_header.layer_count = TCOD_list_size(console_list); if (write_header(gz_file, &xp_header)) { gzclose(gz_file); return false; /* error writing metadata */ } for (i = 0; i < xp_header.layer_count; ++i){ if (write_console(gz_file, TCOD_list_get(console_list, i))) { gzclose(gz_file); return false; /* error writing out console data */ } } if (gzclose(gz_file)) { return false; /* error writing to file */ } return true; } #endif /* TCOD_CONSOLE_SUPPORT */ libtcod-1.6.4+dfsg/src/fov.cpp000066400000000000000000000053301321276576200161620ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include TCODMap::TCODMap(int width,int height) { data = TCOD_map_new(width,height); } void TCODMap::clear(bool transparent, bool walkable) { TCOD_map_clear(data,transparent,walkable); } void TCODMap::setProperties(int x, int y, bool isTransparent, bool isWalkable) { TCOD_map_set_properties(data,x,y,isTransparent,isWalkable); } void TCODMap::copy(const TCODMap *source) { TCOD_map_copy(source->data,data); } void TCODMap::computeFov(int x, int y, int maxRadius, bool light_walls, TCOD_fov_algorithm_t algo) { TCOD_map_compute_fov(data,x,y,maxRadius,light_walls, algo); } bool TCODMap::isInFov(int x, int y) const { return TCOD_map_is_in_fov(data,x,y) != 0; } void TCODMap::setInFov(int x,int y, bool fov) { TCOD_map_set_in_fov(data, x, y, fov); } bool TCODMap::isTransparent(int x, int y) const { return TCOD_map_is_transparent(data,x,y) != 0; } bool TCODMap::isWalkable(int x, int y) const { return TCOD_map_is_walkable(data,x,y) != 0; } int TCODMap::getWidth() const { return TCOD_map_get_width(data); } int TCODMap::getHeight() const { return TCOD_map_get_height(data); } int TCODMap::getNbCells() const { return TCOD_map_get_nb_cells(data); } TCODMap::~TCODMap() { TCOD_map_delete(data); } libtcod-1.6.4+dfsg/src/fov_c.c000066400000000000000000000127511321276576200161310ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include TCOD_map_t TCOD_map_new(int width, int height) { map_t *map=NULL; TCOD_IFNOT(width > 0 && height > 0) return NULL; map=(map_t *)calloc(sizeof(map_t),1); map->width=width; map->height=height; map->nbcells=width*height; map->cells=(cell_t *)calloc(sizeof(cell_t),map->nbcells); return map; } void TCOD_map_copy(TCOD_map_t source, TCOD_map_t dest) { map_t *source_int = (map_t *)source; map_t *dest_int = (map_t *)dest; TCOD_IFNOT(source != NULL && dest != NULL) return; if ( dest_int->nbcells != source_int->nbcells ) { free(dest_int->cells); dest_int->cells=(cell_t *)malloc(sizeof(cell_t)*dest_int->nbcells); } dest_int->width=source_int->width; dest_int->height=source_int->height; dest_int->nbcells=source_int->nbcells; memcpy(dest_int->cells, source_int->cells, sizeof(cell_t) * source_int->nbcells); } void TCOD_map_clear(TCOD_map_t map, bool transparent, bool walkable) { int i; map_t *m = (map_t *)map; cell_t *cell; TCOD_IFNOT(map != NULL) return; cell=m->cells; for (i = 0; i < m->nbcells; i++) { cell->transparent = transparent; cell->walkable = walkable; cell->fov = 0; cell++; } } void TCOD_map_set_properties(TCOD_map_t map, int x, int y, bool is_transparent, bool is_walkable) { map_t *m = (map_t *)map; TCOD_IFNOT(map != NULL) return; TCOD_IFNOT((unsigned)x < (unsigned)m->width && (unsigned)y < (unsigned)m->height) return; m->cells[x+y*m->width].transparent=is_transparent; m->cells[x+y*m->width].walkable=is_walkable; } void TCOD_map_delete(TCOD_map_t map) { map_t *m = (map_t *)map; TCOD_IFNOT(map != NULL) return; free(m->cells); free(m); } void TCOD_map_compute_fov(TCOD_map_t map, int player_x, int player_y, int max_radius, bool light_walls, TCOD_fov_algorithm_t algo) { TCOD_IFNOT(map != NULL) return; switch(algo) { case FOV_BASIC : TCOD_map_compute_fov_circular_raycasting(map,player_x,player_y,max_radius,light_walls); break; case FOV_DIAMOND : TCOD_map_compute_fov_diamond_raycasting(map,player_x,player_y,max_radius,light_walls); break; case FOV_SHADOW : TCOD_map_compute_fov_recursive_shadowcasting(map,player_x,player_y,max_radius,light_walls); break; case FOV_PERMISSIVE_0 : case FOV_PERMISSIVE_1 : case FOV_PERMISSIVE_2 : case FOV_PERMISSIVE_3 : case FOV_PERMISSIVE_4 : case FOV_PERMISSIVE_5 : case FOV_PERMISSIVE_6 : case FOV_PERMISSIVE_7 : case FOV_PERMISSIVE_8 : TCOD_map_compute_fov_permissive2(map,player_x,player_y,max_radius,light_walls, algo-FOV_PERMISSIVE_0); break; case FOV_RESTRICTIVE : TCOD_map_compute_fov_restrictive_shadowcasting(map,player_x,player_y,max_radius,light_walls); break; default:break; } } bool TCOD_map_is_in_fov(TCOD_map_t map, int x, int y) { map_t *m = (map_t *)map; TCOD_IFNOT(map != NULL && (unsigned)x < (unsigned)m->width && (unsigned)y < (unsigned)m->height) return false; return m->cells[x+y*m->width].fov == 1; } void TCOD_map_set_in_fov(TCOD_map_t map, int x, int y, bool fov) { map_t *m = (map_t *)map; TCOD_IFNOT(map != NULL && (unsigned)x < (unsigned)m->width && (unsigned)y < (unsigned)m->height) return; m->cells[x+y*m->width].fov = fov ? 1:0; } bool TCOD_map_is_transparent(TCOD_map_t map, int x, int y) { map_t *m = (map_t *)map; TCOD_IFNOT(map != NULL && (unsigned)x < (unsigned)m->width && (unsigned)y < (unsigned)m->height) return false; return m->cells[x+y*m->width].transparent; } bool TCOD_map_is_walkable(TCOD_map_t map, int x, int y) { map_t *m = (map_t *)map; TCOD_IFNOT(map != NULL && (unsigned)x < (unsigned)m->width && (unsigned)y < (unsigned)m->height) return false; return m->cells[x+y*m->width].walkable; } int TCOD_map_get_width(TCOD_map_t map) { map_t *m = (map_t *)map; TCOD_IFNOT(map != NULL) return 0; return m->width; } int TCOD_map_get_height(TCOD_map_t map) { map_t *m = (map_t *)map; TCOD_IFNOT(map != NULL) return 0; return m->height; } int TCOD_map_get_nb_cells(TCOD_map_t map) { map_t *m = (map_t *)map; TCOD_IFNOT(map != NULL) return 0; return m->nbcells; } libtcod-1.6.4+dfsg/src/fov_circular_raycasting.c000066400000000000000000000174571321276576200217470ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include static void cast_ray(map_t *map, int xo, int yo, int xd, int yd, int r2,bool light_walls) { int curx=xo,cury=yo; bool in=false; bool blocked=false; bool end=false; int offset; TCOD_line_init(xo,yo,xd,yd); offset=curx+cury*map->width; if ( 0 <= offset && offset < map->nbcells ) { in=true; map->cells[offset].fov=1; } while (!end) { end = TCOD_line_step(&curx,&cury); /* reached xd,yd */ offset=curx+cury*map->width; if ( r2 > 0 ) { /* check radius */ int cur_radius=(curx-xo)*(curx-xo)+(cury-yo)*(cury-yo); if ( cur_radius > r2 ) return; } if ( 0 <= offset && offset < map->nbcells ) { in=true; if ( !blocked && ! map->cells[offset].transparent ) { blocked=true; } else if ( blocked ) { return; /* wall */ } if ( light_walls || ! blocked ) map->cells[offset].fov=1; } else if (in) return; /* ray out of map */ } } void TCOD_map_postproc(map_t *map,int x0,int y0, int x1, int y1, int dx, int dy) { int cx,cy; for (cx=x0; cx <= x1; cx++) { for (cy=y0;cy <= y1; cy ++ ) { int x2 = cx+dx; int y2 = cy+dy; unsigned int offset=cx+cy*map->width; if ( offset < (unsigned)map->nbcells && map->cells[offset].fov == 1 && map->cells[offset].transparent ) { if ( x2 >= x0 && x2 <= x1 ) { unsigned int offset2=x2+cy*map->width; if ( offset2 < (unsigned)map->nbcells && ! map->cells[offset2].transparent ) map->cells[offset2].fov=1; } if ( y2 >= y0 && y2 <= y1 ) { unsigned int offset2=cx+y2*map->width; if ( offset2 < (unsigned)map->nbcells && ! map->cells[offset2].transparent ) map->cells[offset2].fov=1; } if ( x2 >= x0 && x2 <= x1 && y2 >= y0 && y2 <= y1 ) { unsigned int offset2=x2+y2*map->width; if ( offset2 < (unsigned)map->nbcells && ! map->cells[offset2].transparent ) map->cells[offset2].fov=1; } } } } } void TCOD_map_compute_fov_circular_raycastingi(TCOD_map_t map, int player_x, int player_y, int max_radius, bool light_walls) { int xo,yo; map_t *m = (map_t *)map; /* circular ray casting */ int xmin=0, ymin=0, xmax=m->width, ymax=m->height; int c; int r2=max_radius*max_radius; if ( max_radius > 0 ) { xmin=MAX(0,player_x-max_radius); ymin=MAX(0,player_y-max_radius); xmax=MIN(m->width,player_x+max_radius+1); ymax=MIN(m->height,player_y+max_radius+1); } for (c=m->nbcells-1; c >= 0; c--) { m->cells[c].fov=0; } xo=xmin; yo=ymin; while ( xo < xmax ) { cast_ray(m,player_x,player_y,xo++,yo,r2,light_walls); } xo=xmax-1;yo=ymin+1; while ( yo < ymax ) { cast_ray(m,player_x,player_y,xo,yo++,r2,light_walls); } xo=xmax-2;yo=ymax-1; while ( xo >= 0 ) { cast_ray(m,player_x,player_y,xo--,yo,r2,light_walls); } xo=xmin;yo=ymax-2; while ( yo > 0 ) { cast_ray(m,player_x,player_y,xo,yo--,r2,light_walls); } if ( light_walls ) { /* post-processing artefact fix */ TCOD_map_postproc(m,xmin,ymin,player_x,player_y,-1,-1); TCOD_map_postproc(m,player_x,ymin,xmax-1,player_y,1,-1); TCOD_map_postproc(m,xmin,player_y,player_x,ymax-1,-1,1); TCOD_map_postproc(m,player_x,player_y,xmax-1,ymax-1,1,1); } } #if 0 #define CELL_RADIUS 0.4f #define RAY_RADIUS 0.2f static bool ray_blocked(map_t *map,float x, float y, int cx, int cy) { int offset=cx+cy*map->width; float d; if ( (unsigned)offset >= (unsigned)map->nbcells ) return false; /* out of the map */ if ( map->cells[offset].transparent ) return false; /* empty cell */ d=(cx-x+0.5f)*(cx-x+0.5f)+(cy-y+0.5f)*(cy-y+0.5f); return d < (CELL_RADIUS+RAY_RADIUS)*(CELL_RADIUS+RAY_RADIUS); } static void cast_rayf(map_t *map, int xo, int yo, int xd, int yd, int r2,bool light_walls) { float fxo=xo+0.5f, fyo=yo+0.5f; float curx=fxo, cury=fyo; float fxd=xd+0.5f; float fyd=yd+0.5f; bool in=false; bool end=false; int offset; float dx=(float)(fxd-curx), dy=(float)(fyd-cury),idx,idy; if ( dx == 0 && dy == 0 ) return; if ( fabs(dx) > fabs(dy) ) { idy = (float)(dy/fabs(dx)); idx = (float)(dx/fabs(dx)); } else { idx = (float)(dx/fabs(dy)); idy = (float)(dy/fabs(dy)); } offset=(int)(curx)+(int)(cury)*map->width; if ( (unsigned)offset < (unsigned)map->nbcells ) { in=true; map->cells[offset].fov=1; } while (!end) { int cx,cy; curx+=idx; cury+=idy; cx=(int)curx; cy=(int)cury; end = (cx==xd && cy==yd); offset=cx+cy*map->width; if ( r2 > 0 ) { /* check radius */ int cur_radius=(int)((curx-fxo)*(curx-fxo)+(cury-fyo)*(cury-fyo)); if ( cur_radius > r2 ) return; } if ( (unsigned)offset < (unsigned)map->nbcells ) { in=true; if ( ray_blocked(map,curx,cury,cx,cy) ) return; if ( curx+RAY_RADIUS > cx+0.5f-CELL_RADIUS && ray_blocked(map,curx,cury,cx+1,cy) ) return; if ( curx-RAY_RADIUS < cx-0.5f+CELL_RADIUS && ray_blocked(map,curx,cury,cx-1,cy) ) return; if ( cury+RAY_RADIUS > cy+0.5f-CELL_RADIUS && ray_blocked(map,curx,cury,cx,cy+1) ) return; if ( cury-RAY_RADIUS < cy-0.5f+CELL_RADIUS && ray_blocked(map,curx,cury,cx,cy-1) ) return; map->cells[offset].fov=1; } else if (in) return; /* ray out of map */ } } #endif void TCOD_map_compute_fov_circular_raycasting(TCOD_map_t map, int player_x, int player_y, int max_radius, bool light_walls) { int xo,yo; map_t *m = (map_t *)map; /* circular ray casting */ int xmin=0, ymin=0, xmax=m->width, ymax=m->height; int c; int r2=max_radius*max_radius; if ( max_radius > 0 ) { xmin=MAX(0,player_x-max_radius); ymin=MAX(0,player_y-max_radius); xmax=MIN(m->width,player_x+max_radius+1); ymax=MIN(m->height,player_y+max_radius+1); } for (c=m->nbcells-1; c >= 0; c--) { m->cells[c].fov=0; } xo=xmin; yo=ymin; while ( xo < xmax ) { cast_ray(m,player_x,player_y,xo++,yo,r2,light_walls); } xo=xmax-1;yo=ymin+1; while ( yo < ymax ) { cast_ray(m,player_x,player_y,xo,yo++,r2,light_walls); } xo=xmax-2;yo=ymax-1; while ( xo >= 0 ) { cast_ray(m,player_x,player_y,xo--,yo,r2,light_walls); } xo=xmin;yo=ymax-2; while ( yo > 0 ) { cast_ray(m,player_x,player_y,xo,yo--,r2,light_walls); } if ( light_walls ) { /* post-processing artefact fix */ TCOD_map_postproc(m,xmin,ymin,player_x,player_y,-1,-1); TCOD_map_postproc(m,player_x,ymin,xmax-1,player_y,1,-1); TCOD_map_postproc(m,xmin,player_y,player_x,ymax-1,-1,1); TCOD_map_postproc(m,player_x,player_y,xmax-1,ymax-1,1,1); } } libtcod-1.6.4+dfsg/src/fov_diamond_raycasting.c000066400000000000000000000151751321276576200215510ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include typedef struct _ray_data_t { int xloc,yloc; /* position */ int xob,yob; /* obscurity vector */ int xerr,yerr; /* bresenham error */ struct _ray_data_t * xinput, * yinput; /* offset of input rays */ bool added; /* already in the fov */ bool ignore; /* non visible. don't bother processing it */ } ray_data_t; static int origx,origy; /* fov origin */ static ray_data_t **raymap; /* result rays */ static ray_data_t *raymap2; /* temporary rays */ static int perimidx; static ray_data_t *new_ray(map_t *m,int x, int y) { ray_data_t *r; if ( (unsigned) (x+origx) >= (unsigned)m->width ) return NULL; if ( (unsigned) (y+origy) >= (unsigned)m->height ) return NULL; r=&raymap2[ x+origx + (y+origy)*m->width ]; r->xloc=x; r->yloc=y; return r; } static void processRay(map_t *m, TCOD_list_t perim, ray_data_t *new_ray, ray_data_t *input_ray) { if ( new_ray ) { int mapx=origx+new_ray->xloc; int mapy=origy+new_ray->yloc; int newrayidx; newrayidx=mapx+mapy*m->width; if ( new_ray->yloc == input_ray->yloc ) new_ray->xinput=input_ray; else new_ray->yinput=input_ray; if (! new_ray->added) { TCOD_list_push(perim,new_ray); new_ray->added=true; raymap[newrayidx] = new_ray; } } } #define IS_OBSCURE(r) ((r->xerr > 0 && r->xerr <= r->xob) || (r->yerr > 0 && r->yerr <= r->yob) ) static void process_x_input(ray_data_t *new_ray, ray_data_t *xinput) { if ( xinput->xob == 0 && xinput->yob == 0 ) return; if ( xinput->xerr > 0 && new_ray->xob == 0) { new_ray->xerr = xinput->xerr - xinput->yob; new_ray->yerr = xinput->yerr + xinput->yob; new_ray->xob=xinput->xob; new_ray->yob=xinput->yob; } if ( xinput->yerr <= 0 && xinput->yob > 0 && xinput->xerr > 0) { new_ray->yerr = xinput->yerr + xinput->yob; new_ray->xerr = xinput->xerr - xinput->yob; new_ray->xob=xinput->xob; new_ray->yob=xinput->yob; } } static void process_y_input(ray_data_t *new_ray, ray_data_t *yinput) { if ( yinput->xob == 0 && yinput->yob == 0 ) return; if ( yinput->yerr > 0 && new_ray->yob == 0) { new_ray->yerr = yinput->yerr - yinput->xob; new_ray->xerr = yinput->xerr + yinput->xob; new_ray->xob=yinput->xob; new_ray->yob=yinput->yob; } if ( yinput->xerr <= 0 && yinput->xob > 0 && yinput->yerr > 0) { new_ray->yerr = yinput->yerr - yinput->xob; new_ray->xerr = yinput->xerr + yinput->xob; new_ray->xob=yinput->xob; new_ray->yob=yinput->yob; } } static void merge_input(map_t *m, ray_data_t *r) { int rayidx=r->xloc+origx+(r->yloc+origy)*m->width; ray_data_t *xi=r->xinput; ray_data_t *yi=r->yinput; if ( xi ) process_x_input(r,xi); if ( yi ) process_y_input(r,yi); if ( ! xi ) { if ( IS_OBSCURE(yi) ) r->ignore=true; } else if ( ! yi ) { if ( IS_OBSCURE(xi) ) r->ignore=true; } else if ( IS_OBSCURE(xi) && IS_OBSCURE(yi) ) { r->ignore=true; } if (! r->ignore && !m->cells[rayidx].transparent) { r->xerr = r->xob = ABS(r->xloc); r->yerr = r->yob = ABS(r->yloc); } } static void expandPerimeterFrom(map_t *m,TCOD_list_t perim,ray_data_t *r) { if ( r->xloc >= 0 ) { processRay(m,perim,new_ray(m,r->xloc+1,r->yloc),r); } if ( r->xloc <= 0 ) { processRay(m,perim,new_ray(m,r->xloc-1,r->yloc),r); } if ( r->yloc >= 0 ) { processRay(m,perim,new_ray(m,r->xloc,r->yloc+1),r); } if ( r->yloc <= 0 ) { processRay(m,perim,new_ray(m,r->xloc,r->yloc-1),r); } } void TCOD_map_compute_fov_diamond_raycasting(TCOD_map_t map, int player_x, int player_y, int max_radius, bool light_walls) { map_t *m = (map_t *)map; TCOD_list_t perim=TCOD_list_allocate(m->nbcells); cell_t *c; ray_data_t **r; int nbcells; int r2=max_radius*max_radius; perimidx=0; raymap=(ray_data_t **)calloc(sizeof(ray_data_t*),m->nbcells); raymap2=(ray_data_t *)calloc(sizeof(ray_data_t),m->nbcells); origx=player_x; origy=player_y; expandPerimeterFrom(m,perim,new_ray(m,0,0)); while ( perimidx < TCOD_list_size(perim) ) { ray_data_t *ray=(ray_data_t *)TCOD_list_get(perim,perimidx); int distance = 0; if ( r2 > 0 ) distance = ((ray->xloc * ray->xloc) + (ray->yloc * ray->yloc)); perimidx++; if ( distance <= r2) { merge_input(m, ray); if ( !ray->ignore ) expandPerimeterFrom(m,perim,ray); } else ray->ignore=true; } /* set fov data */ c=m->cells; r=raymap; nbcells=m->nbcells; while ( nbcells!= 0 ) { if ( *r == NULL || (*r)->ignore || ((*r)->xerr > 0 && (*r)->xerr <= (*r)->xob ) || ((*r)->yerr > 0 && (*r)->yerr <= (*r)->yob ) ) { c->fov=0; } else { c->fov=1; } c++; r++; nbcells--; } m->cells[origx+origy*m->width].fov=1; /* light walls */ if ( light_walls ) { int xmin=0, ymin=0, xmax=m->width, ymax=m->height; if ( max_radius > 0 ) { xmin=MAX(0,player_x-max_radius); ymin=MAX(0,player_y-max_radius); xmax=MIN(m->width,player_x+max_radius+1); ymax=MIN(m->height,player_y+max_radius+1); } TCOD_map_postproc(m,xmin,ymin,player_x,player_y,-1,-1); TCOD_map_postproc(m,player_x,ymin,xmax-1,player_y,1,-1); TCOD_map_postproc(m,xmin,player_y,player_x,ymax-1,-1,1); TCOD_map_postproc(m,player_x,player_y,xmax-1,ymax-1,1,1); } free(raymap); free(raymap2); TCOD_list_delete(perim); } libtcod-1.6.4+dfsg/src/fov_permissive2.c000066400000000000000000000212721321276576200201550ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include /* The size of each square in units */ #define STEP_SIZE 16 /* Jonathon Duerig enhanced permissive FOV */ typedef struct { int xi,yi,xf,yf; } line_t; /* Defines the parameters of the permissiveness */ /* Derived values defining the actual part of the square used as a range. */ static int offset; static int limit; typedef struct _viewbump_t { int x,y; int refcount; struct _viewbump_t *parent; } viewbump_t; typedef struct { line_t shallow_line; line_t steep_line; viewbump_t *shallow_bump; viewbump_t *steep_bump; } view_t; static view_t **current_view=NULL; static view_t *views=NULL; static viewbump_t *bumps=NULL; static int bumpidx=0; #define RELATIVE_SLOPE(l,x,y) (((l)->yf-(l)->yi)*((l)->xf-(x)) - ((l)->xf-(l)->xi)*((l)->yf-(y))) #define BELOW(l,x,y) (RELATIVE_SLOPE(l,x,y) > 0) #define BELOW_OR_COLINEAR(l,x,y) (RELATIVE_SLOPE(l,x,y) >= 0) #define ABOVE(l,x,y) (RELATIVE_SLOPE(l,x,y) < 0) #define ABOVE_OR_COLINEAR(l,x,y) (RELATIVE_SLOPE(l,x,y) <= 0) #define COLINEAR(l,x,y) (RELATIVE_SLOPE(l,x,y) == 0) #define LINE_COLINEAR(l,l2) (COLINEAR(l,(l2)->xi,(l2)->yi) && COLINEAR(l,(l2)->xf,(l2)->yf)) static bool is_blocked(map_t *map, view_t *view, int startX, int startY, int x, int y, int dx, int dy, bool light_walls) { int posx=x*dx/STEP_SIZE+startX; int posy=y*dy/STEP_SIZE+startY; int offset=posx + (posy)*map->width; bool blocked=!map->cells[offset].transparent; if (! blocked || light_walls) map->cells[offset].fov=1; return blocked; } static void add_shallow_bump(int x, int y, view_t *view) { viewbump_t *shallow, *curbump; view->shallow_line.xf=x; view->shallow_line.yf=y; shallow= &bumps[bumpidx++]; shallow->x=x; shallow->y=y; shallow->parent=view->shallow_bump; view->shallow_bump=shallow; curbump=view->steep_bump; while ( curbump ) { if ( ABOVE(&view->shallow_line,curbump->x,curbump->y)) { view->shallow_line.xi=curbump->x; view->shallow_line.yi=curbump->y; } curbump=curbump->parent; } } static void add_steep_bump(int x, int y, view_t *view) { viewbump_t *steep, *curbump; view->steep_line.xf=x; view->steep_line.yf=y; steep=&bumps[bumpidx++]; steep->x=x; steep->y=y; steep->parent=view->steep_bump; view->steep_bump=steep; curbump=view->shallow_bump; while ( curbump ) { if ( BELOW(&view->steep_line,curbump->x,curbump->y)) { view->steep_line.xi=curbump->x; view->steep_line.yi=curbump->y; } curbump=curbump->parent; } } static bool check_view(TCOD_list_t active_views, view_t **it) { view_t *view=*it; line_t *shallow_line=&view->shallow_line; line_t *steep_line=&view->steep_line; if (LINE_COLINEAR(shallow_line,steep_line) && (COLINEAR(shallow_line,offset,limit) || COLINEAR(shallow_line,limit,offset)) ){ /*printf ("deleting view %x\n",it); */ /* slow ! */ TCOD_list_remove_iterator(active_views,(void **)it); return false; } return true; } static void visit_coords(map_t *m,int startX, int startY, int x, int y, int dx, int dy, TCOD_list_t active_views, bool light_walls) { /* top left */ int tlx=x, tly=y+STEP_SIZE; /* bottom right */ int brx=x+STEP_SIZE, bry=y; view_t *view=NULL; while (current_view != (view_t **)TCOD_list_end(active_views)) { view=*current_view; if ( ! BELOW_OR_COLINEAR(&view->steep_line,brx,bry) ) { break; } current_view++; } if ( current_view == (view_t **)TCOD_list_end(active_views) || ABOVE_OR_COLINEAR(&view->shallow_line,tlx,tly)) { /* no more active view */ return; } if ( !is_blocked(m,view,startX,startY,x,y,dx,dy,light_walls) ) return; if ( ABOVE(&view->shallow_line,brx,bry) && BELOW(&view->steep_line,tlx,tly)) { /* view blocked */ /* slow ! */ TCOD_list_remove_iterator(active_views,(void **)current_view); } else if ( ABOVE(&view->shallow_line,brx,bry)) { /* shallow bump */ add_shallow_bump(tlx,tly,view); check_view(active_views,current_view); } else if (BELOW(&view->steep_line,tlx,tly)) { /* steep bump */ add_steep_bump(brx,bry,view); check_view(active_views,current_view); } else { /* view split */ int offset=startX+x*dx/STEP_SIZE + (startY+y*dy/STEP_SIZE)*m->width; view_t *shallower_view= & views[offset]; int view_index=(int)(current_view - (view_t **)TCOD_list_begin(active_views)); view_t **shallower_view_it; view_t **steeper_view_it; *shallower_view=**current_view; /* slow ! */ shallower_view_it = (view_t **)TCOD_list_insert_before(active_views,shallower_view,view_index); steeper_view_it=shallower_view_it+1; current_view=shallower_view_it; add_steep_bump(brx,bry,shallower_view); if (!check_view(active_views,shallower_view_it)) steeper_view_it--; add_shallow_bump(tlx,tly,*steeper_view_it); check_view(active_views,steeper_view_it); if ( view_index > TCOD_list_size(active_views)) current_view=(view_t **)TCOD_list_end(active_views); } } static void check_quadrant(map_t *m,int startX,int startY,int dx, int dy, int extentX,int extentY, bool light_walls) { TCOD_list_t active_views=TCOD_list_new(); line_t shallow_line={offset,limit,extentX*STEP_SIZE,0}; line_t steep_line={limit,offset,0,extentY*STEP_SIZE}; int maxI=extentX+extentY,i=1; view_t *view= &views[startX+startY*m->width]; view->shallow_line=shallow_line; view->steep_line=steep_line; view->shallow_bump=NULL; view->steep_bump=NULL; TCOD_list_push(active_views,view); current_view=(view_t **)TCOD_list_begin(active_views); while ( i != maxI+1 && ! TCOD_list_is_empty(active_views) ) { int startJ=MAX(i-extentX,0); int maxJ=MIN(i,extentY); int j=startJ; while ( j != maxJ+1 && ! TCOD_list_is_empty(active_views) && current_view != (view_t **)TCOD_list_end(active_views) ) { int x=(i - j)*STEP_SIZE; int y=j*STEP_SIZE; visit_coords(m,startX,startY,x,y,dx,dy,active_views, light_walls); j++; } i++; current_view=(view_t **)TCOD_list_begin(active_views); } TCOD_list_delete(active_views); } void TCOD_map_compute_fov_permissive2(TCOD_map_t map, int player_x, int player_y, int max_radius, bool light_walls, int fovType) { int c,minx,maxx,miny,maxy; map_t *m = (map_t *)map; if ( (unsigned)fovType>8 ) TCOD_fatal("Bad permissiveness %d for FOV_PERMISSIVE. Accepted range is [0,8].\n",fovType); offset=8-fovType; limit=8+fovType; /* clean the map */ for (c=m->nbcells-1; c >= 0; c--) { m->cells[c].fov=0; } m->cells[player_x+player_y*m->width].fov=1; /* preallocate views and bumps */ views=(view_t *)calloc(sizeof(view_t),m->width*m->height); bumps=(viewbump_t *)calloc(sizeof(viewbump_t),m->width*m->height); /* set the fov range */ if ( max_radius > 0 ) { minx=MIN(player_x,max_radius); maxx=MIN(m->width-player_x-1,max_radius); miny=MIN(player_y,max_radius); maxy=MIN(m->height-player_y-1,max_radius); } else { minx=player_x; maxx=m->width-player_x-1; miny=player_y; maxy=m->height-player_y-1; } /* calculate fov. precise permissive field of view */ bumpidx=0; check_quadrant(m,player_x,player_y,1,1,maxx,maxy, light_walls); bumpidx=0; check_quadrant(m,player_x,player_y,1,-1,maxx,miny, light_walls); bumpidx=0; check_quadrant(m,player_x,player_y,-1,-1,minx,miny, light_walls); bumpidx=0; check_quadrant(m,player_x,player_y,-1,1,minx,maxy, light_walls); free(bumps); free(views); } libtcod-1.6.4+dfsg/src/fov_recursive_shadowcasting.c000066400000000000000000000073301321276576200226310ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include static int mult[4][8]= { {1,0,0,-1,-1,0,0,1}, {0,1,-1,0,0,-1,1,0}, {0,1,1,0,0,-1,-1,0}, {1,0,0,1,-1,0,0,-1}, }; static void cast_light(map_t *map,int cx, int cy,int row,float start, float end, int radius, int r2, int xx, int xy, int yx, int yy, int id, bool light_walls) { int j; float new_start=0.0f; if ( start < end ) return; for (j=row; j< radius+1; j++) { int dx=-j-1; int dy=-j; bool blocked=false; while ( dx <= 0 ) { int X,Y; dx++; X=cx+dx*xx+dy*xy; Y=cy+dx*yx+dy*yy; if ((unsigned)X < (unsigned)map->width && (unsigned)Y < (unsigned)map->height) { float l_slope,r_slope; int offset; offset=X+Y*map->width; l_slope=(dx-0.5f)/(dy+0.5f); r_slope=(dx+0.5f)/(dy-0.5f); if( start < r_slope ) continue; else if( end > l_slope ) break; if ( dx*dx+dy*dy <= r2 && (light_walls || map->cells[offset].transparent)) map->cells[offset].fov=1; if ( blocked ) { if (!map->cells[offset].transparent) { new_start=r_slope; continue; } else { blocked=false; start=new_start; } } else { if (!map->cells[offset].transparent && j < radius ) { blocked=true; cast_light(map,cx,cy,j+1,start,l_slope,radius,r2,xx,xy,yx,yy,id+1,light_walls); new_start=r_slope; } } } } if ( blocked ) break; } } void TCOD_map_compute_fov_recursive_shadowcasting(TCOD_map_t map, int player_x, int player_y, int max_radius, bool light_walls) { int oct,c,r2; map_t *m = (map_t *)map; /* clean the map */ for (c=m->nbcells-1; c >= 0; c--) { m->cells[c].fov=0; } if ( max_radius == 0 ) { int max_radius_x=m->width-player_x; int max_radius_y=m->height-player_y; max_radius_x=MAX(max_radius_x,player_x); max_radius_y=MAX(max_radius_y,player_y); max_radius = (int)(sqrt(max_radius_x*max_radius_x+max_radius_y*max_radius_y))+1; } r2=max_radius*max_radius; /* recursive shadow casting */ for (oct=0; oct < 8; oct++) cast_light(m,player_x,player_y,1,1.0,0.0,max_radius,r2, mult[0][oct],mult[1][oct],mult[2][oct],mult[3][oct],0,light_walls); m->cells[player_x+player_y*m->width].fov=1; } libtcod-1.6.4+dfsg/src/fov_restrictive.c000066400000000000000000000226101321276576200202450ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Mingos' Restrictive Precise Angle Shadowcasting (MRPAS) v1.2 */ #include #include /* for NULL in VS */ #include #include /* angle ranges */ double * start_angle = NULL; double * end_angle = NULL; /* number of allocated angle pairs */ int allocated = 0; void TCOD_map_compute_fov_restrictive_shadowcasting_quadrant (map_t *m, int player_x, int player_y, int max_radius, bool light_walls, int dx, int dy) { /* octant: vertical edge */ { int iteration = 1; /* iteration of the algo for this octant */ bool done = false; int total_obstacles = 0; int obstacles_in_last_line = 0; double min_angle = 0.0; int x; int y; /* do while there are unblocked slopes left and the algo is within the map's boundaries scan progressive lines/columns from the PC outwards */ y = player_y+dy; /* the outer slope's coordinates (first processed line) */ if (y < 0 || y >= m->height) { done = true; } while (!done) { /* process cells in the line */ double slopes_per_cell = 1.0 / (double)(iteration); double half_slopes = slopes_per_cell * 0.5; int processed_cell = (int)((min_angle + half_slopes) / slopes_per_cell); int minx = MAX(0, player_x - iteration); int maxx = MIN(m->width - 1, player_x + iteration); done = true; for (x = player_x + (processed_cell * dx); x >= minx && x <= maxx; x+=dx) { int c = x + (y * m->width); /* calculate slopes per cell */ bool visible = true; bool extended = false; double centre_slope = (double)processed_cell * slopes_per_cell; double start_slope = centre_slope - half_slopes; double end_slope = centre_slope + half_slopes; if (obstacles_in_last_line > 0) { if ( !( m->cells[c-(m->width * dy)].fov && m->cells[c-(m->width * dy)].transparent ) && !( m->cells[c-(m->width * dy) - dx].fov && m->cells[c-(m->width * dy) - dx].transparent ) ) { visible = false; } else { int idx; for (idx = 0; idx < obstacles_in_last_line && visible; ++idx) { if ( start_slope <= end_angle[idx] && end_slope >= start_angle[idx] ) { if (m->cells[c].transparent) { if ( centre_slope > start_angle[idx] && centre_slope < end_angle[idx] ) { visible = false; } } else { if ( start_slope >= start_angle[idx] && end_slope <= end_angle[idx] ) { visible = false; } else { start_angle[idx] = MIN(start_angle[idx], start_slope); end_angle[idx] = MAX(end_angle[idx], end_slope); extended = true; } } } } } } if (visible) { done = false; m->cells[c].fov = true; /* if the cell is opaque, block the adjacent slopes */ if (!m->cells[c].transparent) { if (min_angle >= start_slope) { min_angle = end_slope; /* if min_angle is applied to the last cell in line, nothing more needs to be checked. */ if (processed_cell == iteration) { done = true; } } else if (!extended) { start_angle[total_obstacles] = start_slope; end_angle[total_obstacles++] = end_slope; } if (!light_walls) { m->cells[c].fov = false; } } } processed_cell++; } if (iteration == max_radius) { done = true; } iteration++; obstacles_in_last_line = total_obstacles; y += dy; if (y < 0 || y >= m->height) { done = true; } } } /* octant: horizontal edge */ { int iteration = 1; /* iteration of the algo for this octant */ bool done = false; int total_obstacles = 0; int obstacles_in_last_line = 0; double min_angle = 0.0; int x; int y; /* do while there are unblocked slopes left and the algo is within the map's boundaries scan progressive lines/columns from the PC outwards */ x = player_x+dx; /*the outer slope's coordinates (first processed line) */ if (x < 0 || x >= m->width) { done = true; } while (!done) { /* process cells in the line */ double slopes_per_cell = 1.0 / (double)(iteration); double half_slopes = slopes_per_cell * 0.5; int processed_cell = (int)((min_angle + half_slopes) / slopes_per_cell); int miny = MAX(0, player_y - iteration); int maxy = MIN(m->height - 1, player_y + iteration); done = true; for (y = player_y + (processed_cell * dy); y >= miny && y <= maxy; y += dy) { int c = x + (y * m->width); /* calculate slopes per cell */ bool visible = true; bool extended = false; double centre_slope = (double)processed_cell * slopes_per_cell; double start_slope = centre_slope - half_slopes; double end_slope = centre_slope + half_slopes; if (obstacles_in_last_line > 0) { if ( !( m->cells[c-dx].fov && m->cells[c-dx].transparent ) && !( m->cells[c-(m->width * dy) - dx].fov && m->cells[c-(m->width * dy) - dx].transparent ) ) { visible = false; } else { int idx; for (idx = 0; idx < obstacles_in_last_line && visible; ++idx) { if ( start_slope <= end_angle[idx] && end_slope >= start_angle[idx] ) { if (m->cells[c].transparent) { if ( centre_slope > start_angle[idx] && centre_slope < end_angle[idx] ) { visible = false; } } else { if ( start_slope >= start_angle[idx] && end_slope <= end_angle[idx] ) { visible = false; } else { start_angle[idx] = MIN(start_angle[idx], start_slope); end_angle[idx] = MAX(end_angle[idx], end_slope); extended = true; } } ++idx; } } } } if (visible) { done = false; m->cells[c].fov = true; /* if the cell is opaque, block the adjacent slopes */ if (!m->cells[c].transparent) { if (min_angle >= start_slope) { min_angle = end_slope; /* if min_angle is applied to the last cell in line, nothing more needs to be checked. */ if (processed_cell == iteration) { done = true; } } else if (!extended) { start_angle[total_obstacles] = start_slope; end_angle[total_obstacles++] = end_slope; } if (!light_walls) { m->cells[c].fov = false; } } } processed_cell++; } if (iteration == max_radius) { done = true; } iteration++; obstacles_in_last_line = total_obstacles; x += dx; if (x < 0 || x >= m->width) { done = true; } } } } void TCOD_map_compute_fov_restrictive_shadowcasting(TCOD_map_t map, int player_x, int player_y, int max_radius, bool light_walls) { map_t *m = (map_t *)map; int max_obstacles; int c; /* first, zero the FOV map */ for(c = m->nbcells - 1; c >= 0; c--) { m->cells[c].fov = false; } /* calculate an approximated (excessive, just in case) maximum number of obstacles per octant */ max_obstacles = m->nbcells / 7; /* check memory for angles */ if (max_obstacles > allocated) { allocated = max_obstacles; if (start_angle != NULL) free(start_angle); if (end_angle != NULL) free(end_angle); start_angle = (double*)calloc(max_obstacles, sizeof(double)); end_angle = (double*)calloc(max_obstacles, sizeof(double)); } /* set PC's position as visible */ m->cells[player_x+(player_y*m->width)].fov = true; /* compute the 4 quadrants of the map */ TCOD_map_compute_fov_restrictive_shadowcasting_quadrant (m, player_x, player_y, max_radius, light_walls, 1, 1); TCOD_map_compute_fov_restrictive_shadowcasting_quadrant (m, player_x, player_y, max_radius, light_walls, 1, -1); TCOD_map_compute_fov_restrictive_shadowcasting_quadrant (m, player_x, player_y, max_radius, light_walls, -1, 1); TCOD_map_compute_fov_restrictive_shadowcasting_quadrant (m, player_x, player_y, max_radius, light_walls, -1, -1); } libtcod-1.6.4+dfsg/src/gui/000077500000000000000000000000001321276576200154475ustar00rootroot00000000000000libtcod-1.6.4+dfsg/src/gui/README.txt000066400000000000000000000001001321276576200171340ustar00rootroot00000000000000Those classes are a C++ widget toolkit built on top of libtcod. libtcod-1.6.4+dfsg/src/gui/button.cpp000066400000000000000000000060111321276576200174640ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include Button::Button(const char *label,const char *tip,widget_callback_t cbk, void *userData) : pressed(false),label(NULL) { if ( label != NULL ) { setLabel(label); } if ( tip != NULL ) setTip(tip); this->x=0; this->y=0; this->userData=userData; this->cbk=cbk; } Button::Button(int x,int y,int width, int height,const char *label,const char *tip,widget_callback_t cbk, void *userData) : pressed(false), label(NULL) { if ( label != NULL ) setLabel(label); if ( tip != NULL ) setTip(tip); w=width; h=height; this->x=x; this->y=y; this->userData=userData; this->cbk=cbk; } Button::~Button() { if ( label ) free(label); } void Button::setLabel(const char *newLabel) { if ( label ) free(label); label=TCOD_strdup(newLabel); } void Button::render() { con->setDefaultBackground(mouseIn ? backFocus : back); con->setDefaultForeground(mouseIn ? foreFocus : fore); if ( w > 0 && h > 0 ) con->rect(x,y,w,h,true,TCOD_BKGND_SET); if ( label ) { if ( pressed && mouseIn ) { con->printEx(x+w/2,y,TCOD_BKGND_NONE,TCOD_CENTER,"-%s-",label); } else { con->printEx(x+w/2,y,TCOD_BKGND_NONE,TCOD_CENTER,label); } } } void Button::computeSize() { if ( label != NULL ) { w=(int)(strlen(label)+2); } else { w=4; } h=1; } void Button::expand(int width, int height) { if ( w < width ) w = width; } void Button::onButtonPress() { pressed=true; } void Button::onButtonRelease() { pressed=false; } void Button::onButtonClick() { if ( cbk ) cbk(this,userData); } libtcod-1.6.4+dfsg/src/gui/container.cpp000066400000000000000000000043071321276576200201410ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include Container::~Container() { content.clearAndDelete(); } void Container::addWidget(Widget *wid) { content.push(wid); widgets.remove(wid); } void Container::removeWidget(Widget *wid) { content.remove(wid); } void Container::setVisible(bool val) { Widget::setVisible(val); } void Container::clear() { content.clearAndDelete(); } void Container::render() { for ( Widget **wid=content.begin(); wid != content.end(); wid ++ ) { if ( (*wid)->isVisible() ) (*wid)->render(); } } void Container::update(const TCOD_key_t k) { Widget::update(k); for ( Widget **wid=content.begin(); wid != content.end(); wid ++ ) { if ( (*wid)->isVisible() ) (*wid)->update(k); } } libtcod-1.6.4+dfsg/src/gui/flatlist.cpp000066400000000000000000000063451321276576200200050ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include FlatList::FlatList(int x,int y,int w, const char **list, const char *label, const char *tip) : TextBox(x,y,w,10,label,NULL,tip),value(list),list(list), onLeftArrow(false),onRightArrow(false),cbk(NULL),data(NULL) { valueToText(); this->w+=2; } FlatList::~FlatList() { } void FlatList::render() { w--; boxx++; TextBox::render(); boxx--; w++; con->setDefaultBackground((onLeftArrow) ? backFocus : back); con->setDefaultForeground((onLeftArrow) ? foreFocus : fore); con->putChar(x+boxx,y,TCOD_CHAR_ARROW_W); con->setDefaultBackground((onRightArrow) ? backFocus : back); con->setDefaultForeground((onRightArrow) ? foreFocus : fore); con->putChar(x+w-1,y,TCOD_CHAR_ARROW_E); } void FlatList::update(TCOD_key_t k) { onLeftArrow=onRightArrow=false; if ( mouse.cx == x+boxx && mouse.cy == y ) onLeftArrow=true; else if ( mouse.cx == x+w-1 && mouse.cy == y ) onRightArrow=true; Widget::update(k); } void FlatList::valueToText() { setText(*value); } void FlatList::textToValue() { const char **ptr=list; while (*ptr) { if ( strcmp(txt,*ptr) == 0 ) { value = ptr; break; } ptr++; } } void FlatList::onButtonClick() { const char **oldValue=value; if ( onLeftArrow ) { if ( value == list ) { while (*value) { value++; } } value--; } else if ( onRightArrow ) { value++; if ( *value == NULL ) value=list; } if ( value != oldValue && cbk ) { valueToText(); cbk(this,*value,data); } } void FlatList::setValue(const char * v) { const char **ptr=list; while (*ptr) { if ( strcmp(v,*ptr) == 0 ) { value = ptr; valueToText(); break; } ptr++; } } void FlatList::setList(const char **l) { value=list=l; valueToText(); } libtcod-1.6.4+dfsg/src/gui/hbox.cpp000066400000000000000000000040131321276576200171110ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include HBox::HBox(int x, int y, int padding) : VBox(x,y,padding) { } void HBox::computeSize() { int curx=x; h=0; for (Widget **wid=content.begin(); wid != content.end(); wid ++ ) { if ( (*wid)->isVisible() ) { (*wid)->y=y; (*wid)->x=curx; (*wid)->computeSize(); if ((*wid)->h > h) h=(*wid)->h; curx+=(*wid)->w+padding; } } w=curx-x; for (Widget **wid=content.begin(); wid != content.end(); wid ++ ) { if ( (*wid)->isVisible() ) { (*wid)->expand((*wid)->w,h); } } } libtcod-1.6.4+dfsg/src/gui/image.cpp000066400000000000000000000037471321276576200172500ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include /* header conflict with image.hpp */ Image::Image(int x,int y,int w, int h, const char *tip) : Widget(x,y,w,h), back(TCODColor::black) { if ( tip ) setTip(tip); } Image::~Image() { } void Image::render() { con->setDefaultBackground(back); con->rect(x,y,w,h,TCOD_BKGND_SET); } void Image::setBackgroundColor(const TCODColor col) { back=col; } void Image::expand(int width, int height) { if ( width > w ) w=width; if ( height > h ) h=height; } libtcod-1.6.4+dfsg/src/gui/label.cpp000066400000000000000000000037131321276576200172360ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include Label::Label(int x, int y, const char *label, const char *tip) : Widget(x,y,0,1) { this->label=label; if ( tip ) setTip(tip); } void Label::render() { con->setDefaultBackground(back); con->setDefaultForeground(fore); con->printEx(x,y,TCOD_BKGND_NONE,TCOD_LEFT,label); } void Label::computeSize() { if ( label ) w=(int)strlen(label); else w=0; } void Label::expand(int width, int height) { if ( w < width ) w=width; } libtcod-1.6.4+dfsg/src/gui/radiobutton.cpp000066400000000000000000000042541321276576200205120ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include RadioButton *RadioButton::groupSelect[512]; int RadioButton::defaultGroup=0; static bool init=false; void RadioButton::select() { if (!init) { memset(groupSelect,0,sizeof(RadioButton *)*512); init=true; } groupSelect[group]=this; } void RadioButton::unSelect() { if (!init) { memset(groupSelect,0,sizeof(RadioButton *)*512); init=true; } groupSelect[group]=NULL; } void RadioButton::unSelectGroup(int group) { groupSelect[group]=NULL; } void RadioButton::render() { Button::render(); if ( groupSelect[group] == this ) { con->setChar(x,y,'>'); } } void RadioButton::onButtonClick() { select(); Button::onButtonClick(); } libtcod-1.6.4+dfsg/src/gui/slider.cpp000066400000000000000000000073241321276576200174430ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include Slider::Slider(int x,int y,int w, float min, float max, const char *label, const char *tip) : TextBox(x,y,w,10,label,NULL,tip),min(min),max(max),value((min+max)*0.5f),sensitivity(1.0f), onArrows(false),drag(false),fmt(NULL),cbk(NULL),data(NULL) { valueToText(); this->w+=2; } Slider::~Slider() { if (fmt) free(fmt); } void Slider::setFormat(const char *fmt) { if (this->fmt) free(this->fmt); if (fmt) this->fmt = TCOD_strdup(fmt); else this->fmt = NULL; valueToText(); } void Slider::render() { w-=2; TextBox::render(); w+=2; con->setDefaultBackground((onArrows || drag) ? backFocus : back); con->setDefaultForeground((onArrows || drag) ? foreFocus : fore); con->rect(x+w-2,y,2,1,TCOD_BKGND_SET); con->setChar(x+w-2,y,TCOD_CHAR_ARROW_W); con->setChar(x+w-1,y,TCOD_CHAR_ARROW_E); } void Slider::update(TCOD_key_t k) { float oldValue=value; TextBox::update(k); textToValue(); if ( mouse.cx >= x+w-2 && mouse.cx < x+w && mouse.cy == y ) onArrows=true; else onArrows=false; if ( drag ) { if ( dragy == -1 ) { dragx = mouse.x; dragy = mouse.y; } else { float mdx = (float)((mouse.x-dragx)*sensitivity) / (con->getWidth()*8); float mdy = (float)((mouse.y-dragy)*sensitivity) / (con->getHeight()*8); float oldValue=value; if ( fabs(mdy) > fabs(mdx) ) mdx=-mdy; value = dragValue+(max-min)*mdx; value=CLAMP(min,max,value); if ( value != oldValue ) { valueToText(); textToValue(); } } } if ( value != oldValue && cbk ) { cbk(this,value,data); } } void Slider::valueToText() { char tmp[128]; sprintf(tmp, fmt ? fmt : "%.2f",value); setText(tmp); } void Slider::textToValue() { #ifdef TCOD_VISUAL_STUDIO value=(float)atof(txt); #else char *endptr; float f=strtof(txt,&endptr); if ( f != 0.0f || endptr != txt ) value=f; #endif } void Slider::setValue(float value) { this->value=CLAMP(min,max,value); valueToText(); } void Slider::onButtonPress() { if ( onArrows ) { drag=true; dragy=-1; dragValue=value; TCODMouse::showCursor(false); } } void Slider::onButtonRelease() { if ( drag ) { drag=false; TCODMouse::move((x+w-2)*8,y*8); TCODMouse::showCursor(true); } } libtcod-1.6.4+dfsg/src/gui/statusbar.cpp000066400000000000000000000034241321276576200201660ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include void StatusBar::render() { con->setDefaultBackground(back); con->rect(x,y,w,h,true,TCOD_BKGND_SET); if ( focus && focus->tip ) { con->setDefaultForeground(fore); con->printRectEx(x+1,y,w,h,TCOD_BKGND_NONE,TCOD_LEFT,focus->tip); } } libtcod-1.6.4+dfsg/src/gui/textbox.cpp000066400000000000000000000114661321276576200176600ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include float TextBox::blinkingDelay=0.5f; TextBox::TextBox(int x,int y,int w, int maxw, const char *label, const char *value, const char *tip) : Widget(x,y,w,1),txt(NULL),blink(0.0f),pos(0),offset(0),maxw(maxw),insert(true),txtcbk(NULL), data(NULL) { if ( maxw > 0 ) { txt = new char[maxw+1]; memset(txt,0,sizeof(char)*(maxw+1)); if ( value ) { strncpy(txt,value,maxw); } } if ( tip ) setTip(tip); if ( label ) this->label=TCOD_strdup(label); boxw=w; if (label ) { boxx=(int)strlen(label)+1; this->w+= boxx; } } TextBox::~TextBox() { if ( txt ) delete [] txt; if ( label ) free(label); } void TextBox::setText(const char *txt) { strncpy(this->txt,txt,maxw); } void TextBox::render() { con->setDefaultBackground(back); con->setDefaultForeground(fore); con->rect(x,y,w,h,true,TCOD_BKGND_SET); if ( label ) con->printEx(x,y,TCOD_BKGND_NONE,TCOD_LEFT,label); con->setDefaultBackground(keyboardFocus == this ? foreFocus : fore); con->setDefaultForeground(keyboardFocus == this ? backFocus : back); con->rect(x+boxx,y,boxw,h,false,TCOD_BKGND_SET); int len=(int)strlen(txt)-offset; if (len > boxw) len = boxw; if ( txt ) con->printEx(x+boxx,y,TCOD_BKGND_NONE,TCOD_LEFT,"%.*s",len,&txt[offset]); if (keyboardFocus == this && blink > 0.0f) { if (insert) { con->setCharBackground(x+boxx+pos-offset,y,fore); con->setCharForeground(x+boxx+pos-offset,y,back); } else { con->setCharBackground(x+boxx+pos-offset,y,back); con->setCharForeground(x+boxx+pos-offset,y,fore); } } } void TextBox::update(TCOD_key_t k) { if ( keyboardFocus == this ) { blink -= elapsed; if ( blink < -blinkingDelay ) blink += 2*blinkingDelay; if ( k.vk == TCODK_CHAR || (k.vk >= TCODK_0 && k.vk <= TCODK_9) || (k.vk >= TCODK_KP0 && k.vk <= TCODK_KP9) ) { if ( ! insert || (int)strlen(txt) < maxw ) { if ( insert && pos < (int)strlen(txt) ) { for (int i=(int)strlen(txt); i >= pos; i-- ) { txt[i+1]=txt[i]; } } txt[pos]=k.c; if ( pos < maxw ) pos++; if ( pos >= w ) offset = pos-w+1; if (txtcbk) txtcbk(this,txt,data); } blink=blinkingDelay; } switch ( k.vk ) { case TCODK_LEFT : if (pos > 0) pos--; if ( pos < offset ) offset=pos; blink=blinkingDelay; break; case TCODK_RIGHT : if (pos < (int)strlen(txt)) pos++; if ( pos >= w ) offset = pos-w+1; blink=blinkingDelay; break; case TCODK_HOME : pos = offset = 0; blink=blinkingDelay; break; case TCODK_BACKSPACE : if (pos > 0) { pos--; for (uint32_t i=pos; i <= strlen(txt); i++ ) { txt[i]=txt[i+1]; } if (txtcbk) txtcbk(this,txt,data); if ( pos < offset ) offset=pos; } blink=blinkingDelay; break; case TCODK_DELETE : if (pos < (int)strlen(txt)) { for (uint32_t i=pos; i <= strlen(txt); i++ ) { txt[i]=txt[i+1]; } if (txtcbk) txtcbk(this,txt,data); } blink=blinkingDelay; break; /* case TCODK_INSERT : insert=!insert; blink=blinkingDelay; break; */ case TCODK_END : pos = (int)strlen(txt); if ( pos >= w ) offset = pos-w+1; blink=blinkingDelay; break; default:break; } } Widget::update(k); } void TextBox::onButtonClick() { if ( mouse.cx >= x+boxx && mouse.cx < x+boxx+boxw ) keyboardFocus=this; } libtcod-1.6.4+dfsg/src/gui/togglebutton.cpp000066400000000000000000000042521321276576200206730ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include void ToggleButton::render() { con->setDefaultBackground(mouseIn ? backFocus : back); con->setDefaultForeground(mouseIn ? foreFocus : fore); con->rect(x,y,w,h,true,TCOD_BKGND_SET); if ( label ) { con->printEx(x,y,TCOD_BKGND_NONE,TCOD_LEFT,"%c %s",pressed ? TCOD_CHAR_CHECKBOX_SET : TCOD_CHAR_CHECKBOX_UNSET, label); } else { con->printEx(x,y,TCOD_BKGND_NONE,TCOD_LEFT,"%c",pressed ? TCOD_CHAR_CHECKBOX_SET : TCOD_CHAR_CHECKBOX_UNSET); } } void ToggleButton::onButtonPress() { } void ToggleButton::onButtonRelease() { } void ToggleButton::onButtonClick() { pressed=!pressed; if ( cbk ) cbk(this,userData); } libtcod-1.6.4+dfsg/src/gui/toolbar.cpp000066400000000000000000000074061321276576200176240ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include class Separator : public Widget { public : Separator(const char *txt, const char *tip=NULL) : Widget(0,0,0,1),txt(NULL) { if ( txt ) { this->txt=TCOD_strdup(txt); } if ( tip ) setTip(tip); } virtual ~Separator() { if ( txt ) { free(txt); } } void computeSize() { w = (txt ? (int)strlen(txt)+2 : 0 ); } void expand(int width, int height) { if ( w < width ) w=width; } void render() { con->setDefaultBackground(back); con->setDefaultForeground(fore); con->hline(x,y,w, TCOD_BKGND_SET); con->setChar(x-1,y,TCOD_CHAR_TEEE); con->setChar(x+w,y,TCOD_CHAR_TEEW); con->setDefaultBackground(fore); con->setDefaultForeground(back); con->printEx(x+w/2,y,TCOD_BKGND_SET,TCOD_CENTER," %s ",txt); } char *txt; }; ToolBar::ToolBar(int x, int y, const char *name, const char *tip) : Container(x,y,0,2),name(NULL),fixedWidth(0) { if ( name ) { this->name = TCOD_strdup(name); w = (int)strlen(name)+4; } if ( tip ) setTip(tip); } ToolBar::ToolBar(int x, int y, int w, const char *name, const char *tip) : Container(x,y,w,2),name(NULL),fixedWidth(w) { if ( name ) { this->name = TCOD_strdup(name); fixedWidth = w = MAX((int)strlen(name)+4,w); } if ( tip ) setTip(tip); } ToolBar::~ToolBar() { if ( name ) free(name); } void ToolBar::setName(const char *name) { if ( this->name ) free(this->name); if ( name ) { this->name = TCOD_strdup(name); fixedWidth = MAX((int)strlen(name)+4,fixedWidth); } else { name=NULL; } } void ToolBar::render() { con->setDefaultBackground(back); con->setDefaultForeground(fore); con->printFrame(x,y,w,h,true,TCOD_BKGND_SET,name); Container::render(); } void ToolBar::computeSize() { int cury=y+1; w=name ? (int)strlen(name)+4 : 2; for (Widget **wid=content.begin(); wid != content.end(); wid ++ ) { if ( (*wid)->isVisible() ) { (*wid)->x=x+1; (*wid)->y=cury; (*wid)->computeSize(); if ((*wid)->w +2 > w) w=(*wid)->w + 2; cury+=(*wid)->h; } } if ( w < fixedWidth ) w=fixedWidth; h=cury-y+1; for (Widget **wid=content.begin(); wid != content.end(); wid ++ ) { if ( (*wid)->isVisible() ) { (*wid)->expand(w-2,(*wid)->h); } } } void ToolBar::addSeparator(const char *txt, const char *tip) { addWidget(new Separator(txt,tip)); } libtcod-1.6.4+dfsg/src/gui/vbox.cpp000066400000000000000000000037141321276576200171360ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include void VBox::computeSize() { int cury=y; w=0; for (Widget **wid=content.begin(); wid != content.end(); wid ++ ) { if ( (*wid)->isVisible() ) { (*wid)->x=x; (*wid)->y=cury; (*wid)->computeSize(); if ((*wid)->w > w) w=(*wid)->w; cury+=(*wid)->h+padding; } } h=cury-y; for (Widget **wid=content.begin(); wid != content.end(); wid ++ ) { if ( (*wid)->isVisible() ) { (*wid)->expand(w,(*wid)->h); } } } libtcod-1.6.4+dfsg/src/gui/widget.cpp000066400000000000000000000102461321276576200174410ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include TCODColor Widget::back=TCODColor(40,40,120); TCODColor Widget::fore=TCODColor(220,220,180); TCODColor Widget::backFocus=TCODColor(70,70,130); TCODColor Widget::foreFocus=TCODColor(255,255,255); TCODConsole *Widget::con=NULL; TCODList Widget::widgets; TCOD_mouse_t Widget::mouse; float Widget::elapsed; Widget *Widget::focus=NULL; Widget *Widget::keyboardFocus=NULL; Widget::Widget() : x(0),y(0),w(0),h(0),tip(NULL),mouseIn(false),mouseL(false),visible(true) { widgets.push(this); } Widget::Widget(int x,int y) : x(x),y(y),w(0),h(0),tip(NULL),mouseIn(false),mouseL(false),visible(true) { widgets.push(this); } Widget::Widget(int x,int y, int w, int h) : x(x),y(y),w(w),h(h),tip(NULL),mouseIn(false),mouseL(false),visible(true) { widgets.push(this); } Widget::~Widget() { if ( tip ) free(tip); if ( focus == this ) focus=NULL; widgets.remove(this); } void Widget::setBackgroundColor(const TCODColor col,const TCODColor colFocus) { back=col; backFocus=colFocus; } void Widget::setForegroundColor(const TCODColor col,const TCODColor colFocus) { fore=col; foreFocus=colFocus; } void Widget::setConsole(TCODConsole *console) { con=console; } void Widget::update(const TCOD_key_t k) { bool curs=TCODMouse::isCursorVisible(); if ( curs ) { if ( mouse.cx >= x && mouse.cx < x+w && mouse.cy >= y && mouse.cy < y+h ) { if ( ! mouseIn ) { mouseIn = true; onMouseIn(); } if ( focus != this ) { focus=this; } } else { if ( mouseIn ) { mouseIn = false; onMouseOut(); } mouseL=false; if ( this == focus ) { focus = NULL; } } } if ( mouseIn || (! curs && this == focus ) ) { if ( mouse.lbutton && ! mouseL ) { mouseL = true; onButtonPress(); } else if (! mouse.lbutton && mouseL ) { onButtonRelease(); keyboardFocus=NULL; if ( mouseL ) onButtonClick(); mouseL=false; } else if ( mouse.lbutton_pressed ) { keyboardFocus=NULL; onButtonClick(); } } } void Widget::updateWidgetsIntern(const TCOD_key_t k) { elapsed=TCODSystem::getLastFrameLength(); for (Widget **w=widgets.begin(); w!= widgets.end(); w++) { if ( (*w)->isVisible() ) { (*w)->computeSize(); (*w)->update(k); } } } void Widget::updateWidgets(const TCOD_key_t k,const TCOD_mouse_t pmouse) { mouse=pmouse; updateWidgetsIntern(k); } void Widget::renderWidgets() { if (!con) con=TCODConsole::root; for (Widget **w=widgets.begin(); w!= widgets.end(); w++) { if ((*w)->isVisible()) (*w)->render(); } } void Widget::move(int x,int y) { this->x=x; this->y=y; } void Widget::setTip(const char *tip) { if ( this->tip ) free(this->tip); this->tip = TCOD_strdup(tip); } libtcod-1.6.4+dfsg/src/heightmap.cpp000066400000000000000000000150361321276576200173420ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include TCODHeightMap::TCODHeightMap(int w, int h) : w(w),h(h) { values = new float[w*h]; memset(values,0,sizeof(float)*w*h); } TCODHeightMap::~TCODHeightMap() { delete [] values; } void TCODHeightMap::clear() { TCOD_heightmap_t hm={w,h,values}; TCOD_heightmap_clear(&hm); } void TCODHeightMap::normalize(float newMin, float newMax) { TCOD_heightmap_t hm={w,h,values}; TCOD_heightmap_normalize(&hm,newMin,newMax); } void TCODHeightMap::getMinMax(float *min, float *max) const { TCOD_heightmap_t hm={w,h,values}; TCOD_heightmap_get_minmax(&hm,min,max); } void TCODHeightMap::addHill(float hx, float hy, float hradius, float height) { TCOD_heightmap_t hm={w,h,values}; TCOD_heightmap_add_hill(&hm,hx,hy,hradius,height); } void TCODHeightMap::digHill(float hx, float hy, float hradius, float height) { TCOD_heightmap_t hm={w,h,values}; TCOD_heightmap_dig_hill(&hm,hx,hy,hradius,height); } void TCODHeightMap::copy(const TCODHeightMap *source) { TCOD_heightmap_t hm_source={source->w,source->h,source->values}; TCOD_heightmap_t hm_dest={w,h,values}; TCOD_heightmap_copy(&hm_source,&hm_dest); } void TCODHeightMap::addFbm(TCODNoise *noise, float mulx, float muly, float addx, float addy, float octaves, float delta, float scale) { TCOD_heightmap_t hm={w,h,values}; TCOD_heightmap_add_fbm(&hm,noise->data,mulx,muly,addx,addy,octaves,delta,scale); } void TCODHeightMap::scaleFbm(TCODNoise *noise, float mulx, float muly, float addx, float addy, float octaves, float delta, float scale) { TCOD_heightmap_t hm={w,h,values}; TCOD_heightmap_scale_fbm(&hm,noise->data,mulx,muly,addx,addy,octaves,delta,scale); } float TCODHeightMap::getInterpolatedValue(float x, float y) const { TCOD_heightmap_t hm={w,h,values}; return TCOD_heightmap_get_interpolated_value(&hm,x,y); } void TCODHeightMap::getNormal(float x, float y,float n[3], float waterHeight) const { TCOD_heightmap_t hm={w,h,values}; return TCOD_heightmap_get_normal(&hm,x,y,n,waterHeight); } void TCODHeightMap::digBezier(int px[4], int py[4], float startRadius, float startDepth, float endRadius, float endDepth) { TCOD_heightmap_t hm={w,h,values}; TCOD_heightmap_dig_bezier(&hm,px,py,startRadius,startDepth,endRadius,endDepth); } bool TCODHeightMap::hasLandOnBorder(float seaLevel) const { TCOD_heightmap_t hm={w,h,values}; return TCOD_heightmap_has_land_on_border(&hm,seaLevel) != 0; } void TCODHeightMap::islandify(float seaLevel,TCODRandom *rnd) { TCOD_heightmap_t hm={w,h,values}; return TCOD_heightmap_islandify(&hm,seaLevel,rnd->data); } void TCODHeightMap::add(float f) { TCOD_heightmap_t hm={w,h,values}; TCOD_heightmap_add(&hm,f); } int TCODHeightMap::countCells(float min,float max) const { TCOD_heightmap_t hm={w,h,values}; return TCOD_heightmap_count_cells(&hm,min,max); } void TCODHeightMap::scale(float f) { TCOD_heightmap_t hm={w,h,values}; TCOD_heightmap_scale(&hm,f); } void TCODHeightMap::clamp(float min, float max) { TCOD_heightmap_t hm={w,h,values}; TCOD_heightmap_clamp(&hm,min,max); } void TCODHeightMap::lerp(const TCODHeightMap *a, const TCODHeightMap *b,float coef) { TCOD_heightmap_t hm1={a->w,a->h,a->values}; TCOD_heightmap_t hm2={b->w,b->h,b->values}; TCOD_heightmap_t hmres={w,h,values}; TCOD_heightmap_lerp_hm(&hm1,&hm2,&hmres,coef); } void TCODHeightMap::add(const TCODHeightMap *a, const TCODHeightMap *b) { TCOD_heightmap_t hm1={a->w,a->h,a->values}; TCOD_heightmap_t hm2={b->w,b->h,b->values}; TCOD_heightmap_t hmres={w,h,values}; TCOD_heightmap_add_hm(&hm1,&hm2,&hmres); } void TCODHeightMap::multiply(const TCODHeightMap *a, const TCODHeightMap *b) { TCOD_heightmap_t hm1={a->w,a->h,a->values}; TCOD_heightmap_t hm2={b->w,b->h,b->values}; TCOD_heightmap_t hmres={w,h,values}; TCOD_heightmap_multiply_hm(&hm1,&hm2,&hmres); } float TCODHeightMap::getSlope(int x, int y) const { TCOD_heightmap_t hm={w,h,values}; return TCOD_heightmap_get_slope(&hm,x,y); } void TCODHeightMap::rainErosion(int nbDrops, float erosionCoef,float agregationCoef, TCODRandom *rnd) { TCOD_heightmap_t hm={w,h,values}; TCOD_heightmap_rain_erosion(&hm, nbDrops, erosionCoef, agregationCoef, rnd->data); } void TCODHeightMap::kernelTransform(int kernelSize, const int *dx, const int *dy, const float *weight, float minLevel,float maxLevel) { TCOD_heightmap_t hm={w,h,values}; TCOD_heightmap_kernel_transform(&hm, kernelSize,dx,dy,weight,minLevel, maxLevel); } void TCODHeightMap::addVoronoi(int nbPoints, int nbCoef, const float *coef,TCODRandom *rnd) { TCOD_heightmap_t hm={w,h,values}; TCOD_heightmap_add_voronoi(&hm, nbPoints, nbCoef, coef, rnd->data); } #if 0 void TCODHeightMap::heatErosion(int nbPass,float minSlope,float erosionCoef,float agregationCoef,TCODRandom *rnd) { TCOD_heightmap_t hm={w,h,values}; TCOD_heightmap_heat_erosion(&hm, nbPass, minSlope, erosionCoef, agregationCoef, rnd->data); } #endif void TCODHeightMap::midPointDisplacement(TCODRandom *rnd, float roughness) { TCOD_heightmap_t hm={w,h,values}; if ( ! rnd ) rnd = TCODRandom::getInstance(); TCOD_heightmap_mid_point_displacement(&hm, rnd->data, roughness); } libtcod-1.6.4+dfsg/src/heightmap_c.c000066400000000000000000000406571321276576200173130ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #define GET_VALUE(hm,x,y) (hm)->values[(x)+(y)*(hm)->w] TCOD_heightmap_t *TCOD_heightmap_new(int w,int h) { TCOD_heightmap_t *hm=(TCOD_heightmap_t *)malloc(sizeof(TCOD_heightmap_t)); hm->values = (float *)calloc(sizeof(float),w*h); hm->w=w; hm->h=h; return hm; } void TCOD_heightmap_delete(TCOD_heightmap_t *hm) { free(hm->values); free(hm); } void TCOD_heightmap_clear(TCOD_heightmap_t *hm) { memset(hm->values,0,hm->w*hm->h*sizeof(float)); } float TCOD_heightmap_get_value(const TCOD_heightmap_t *hm, int x, int y) { return GET_VALUE(hm,x,y); } void TCOD_heightmap_set_value(TCOD_heightmap_t *hm, int x, int y, float value) { GET_VALUE(hm,x,y)=value; } void TCOD_heightmap_get_minmax(const TCOD_heightmap_t *hm, float *min, float *max) { float curmax=hm->values[0]; float curmin=hm->values[0]; int x,y; float *value = hm->values; /* get max and min height */ for (y=0; y < hm->h; y++) { for (x=0; x < hm->w; x++) { float val=*value; if ( val > curmax ) curmax = val; else if ( val < curmin ) curmin = val; value++; } } *min=curmin; *max=curmax; } void TCOD_heightmap_normalize(TCOD_heightmap_t *hm, float min, float max) { float curmin,curmax; int x,y; float invmax; float *value = hm->values; TCOD_heightmap_get_minmax(hm,&curmin,&curmax); if (curmax - curmin == 0.0f) invmax=0.0f; else invmax = (max-min) / (curmax-curmin); /* normalize */ for (y=0; y < hm->h; y++) { for (x=0; x < hm->w; x++) { *value = min + (*value - curmin) * invmax ; value++; } } } void TCOD_heightmap_add_hill(TCOD_heightmap_t *hm, float hx, float hy, float hradius, float hheight) { int x,y; float hradius2=hradius*hradius; float coef=hheight / hradius2; int minx=(int)MAX(0,hx-hradius); int maxx=(int)MIN(hm->w,hx+hradius); int miny=(int)MAX(0,hy-hradius); int maxy=(int)MIN(hm->h,hy+hradius); for (x=minx; x < maxx; x++) { float xdist=( x - hx )*( x - hx ); for (y=miny; y < maxy; y++) { float z = hradius2 - xdist - (y - hy)*(y - hy); if ( z > 0.0 ) GET_VALUE(hm,x,y) += z * coef; } } } void TCOD_heightmap_dig_hill(TCOD_heightmap_t *hm, float hx, float hy, float hradius, float hheight) { int x,y; float hradius2=hradius*hradius; float coef=hheight / hradius2; int minx=(int)MAX(0,hx-hradius); int maxx=(int)MIN(hm->w,hx+hradius); int miny=(int)MAX(0,hy-hradius); int maxy=(int)MIN(hm->h,hy+hradius); for (x=minx; x < maxx; x++) { float xdist=( x - hx )*( x - hx ); for (y=miny; y < maxy; y++) { float dist=xdist + (y - hy)*(y - hy); if ( dist < hradius2 ) { float z = (hradius2 - dist) * coef; if ( hheight > 0.0 ) { if ( GET_VALUE(hm,x,y) < z ) GET_VALUE(hm,x,y) = z; } else { if ( GET_VALUE(hm,x,y) > z ) GET_VALUE(hm,x,y) = z; } } } } } void TCOD_heightmap_copy(const TCOD_heightmap_t *hm_source,TCOD_heightmap_t *hm_dest) { if ( hm_source->w != hm_dest->w || hm_source->h != hm_dest->h) return; memcpy(hm_dest->values,hm_source->values,sizeof(float)*hm_source->w*hm_source->h); } void TCOD_heightmap_add_fbm(TCOD_heightmap_t *hm, TCOD_noise_t noise,float mulx, float muly, float addx, float addy, float octaves, float delta, float scale) { int x,y; float xcoef=mulx / hm->w; float ycoef=muly / hm->h; float min=1.0f; float max=0.0f; for (x=0; x < hm->w; x++) { float f[2]; int offset=x; f[0] = (x + addx) * xcoef; for (y=0; y < hm->h; y++) { float value; f[1] = (y + addy)*ycoef; value=delta+TCOD_noise_get_fbm(noise,f,octaves)*scale; hm->values[offset] += value; if ( value < min ) min = value; if ( value > max ) max=value; offset+=hm->w; } } } void TCOD_heightmap_scale_fbm(TCOD_heightmap_t *hm, TCOD_noise_t noise,float mulx, float muly, float addx, float addy, float octaves, float delta, float scale) { int x,y; float xcoef=mulx / hm->w; float ycoef=muly / hm->h; for (x=0; x < hm->w; x++) { float f[2]; int offset=x; f[0] = (x + addx) * xcoef; for (y=0; y < hm->h; y++) { f[1] = (y + addy)*ycoef; hm->values[offset] *= (delta+TCOD_noise_get_fbm(noise,f,octaves)*scale); offset+=hm->w; } } } float TCOD_heightmap_get_interpolated_value(const TCOD_heightmap_t *hm, float x, float y) { int ix = (int) x; int iy = (int) y; if ( ix >= hm->w-1 || iy >= hm->h-1 ) { return GET_VALUE(hm,ix,iy); } else { float dx = x - ix; float dy = y - iy; float c1 = GET_VALUE(hm,ix,iy); float c2 = GET_VALUE(hm,ix+1,iy); float c3 = GET_VALUE(hm,ix,iy+1); float c4 = GET_VALUE(hm,ix+1,iy+1); float top = (1.0f-dx)*c1 + dx*c2; float bottom = (1.0f-dx)*c3 + dx*c4; return (1.0f-dy)*top + dy*bottom; } } void TCOD_heightmap_get_normal(const TCOD_heightmap_t *hm, float x, float y, float n[3], float waterLevel) { float h0,hx,hy,invlen; /* map heights at x,y x+1,y and x,y+1 */ n[0]=0.0f;n[1]=0.0f;n[2]=1.0f; if ( x >= hm->w-1 || y >= hm->h-1 ) return; h0 = TCOD_heightmap_get_interpolated_value(hm,x,y); if ( h0 < waterLevel ) h0=waterLevel; hx = TCOD_heightmap_get_interpolated_value(hm,x+1,y); if ( hx < waterLevel ) hx=waterLevel; hy = TCOD_heightmap_get_interpolated_value(hm,x,y+1); if ( hy < waterLevel ) hy=waterLevel; /* vx = 1 vy = 0 */ /* 0 1 */ /* hx-h0 hy-h0 */ /* vz = vx cross vy */ n[0] = 255*(h0-hx); n[1] = 255*(h0-hy); n[2] = 16.0f; /* normalize */ invlen=1.0f / (float)sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]); n[0]*=invlen; n[1]*=invlen; n[2]*=invlen; } void TCOD_heightmap_dig_bezier(TCOD_heightmap_t *hm, int px[4], int py[4], float startRadius, float startDepth, float endRadius, float endDepth) { int xFrom=px[0]; int yFrom=py[0]; float t; for ( t=0.0f;t <= 1.0f ; t += 0.001f ) { int xTo,yTo; float it=1.0f-t; xTo=(int)(px[0]*it*it*it + 3*px[1]*t*it*it + 3*px[2]*t*t*it + px[3]*t*t*t); yTo=(int)(py[0]*it*it*it + 3*py[1]*t*it*it + 3*py[2]*t*t*it + py[3]*t*t*t); if ( xTo != xFrom || yTo != yFrom ) { float radius=startRadius+(endRadius-startRadius)*t; float depth=startDepth+(endDepth-startDepth)*t; TCOD_heightmap_dig_hill(hm,(float)xTo,(float)yTo,radius,depth); xFrom=xTo; yFrom=yTo; } } } bool TCOD_heightmap_has_land_on_border(const TCOD_heightmap_t *hm, float waterLevel) { int x,y; for (x=0; x < hm->w; x++) { if ( GET_VALUE(hm,x,0) > waterLevel || GET_VALUE(hm,x,hm->h-1) > waterLevel ) { return true; } } for (y=0; y < hm->h; y++) { if ( GET_VALUE(hm,0,y) > waterLevel || GET_VALUE(hm,hm->w-1,y) > waterLevel ) { return true; } } return false; } void TCOD_heightmap_islandify(TCOD_heightmap_t *hm, float seaLevel,TCOD_random_t rnd) { /* TODO */ } void TCOD_heightmap_add(TCOD_heightmap_t *hm, float value) { int i; for (i=0; i < hm->w*hm->h; i++ ) hm->values[i]+=value; } int TCOD_heightmap_count_cells(const TCOD_heightmap_t *hm, float min, float max) { int count=0,i; for (i=0; i < hm->w*hm->h; i++ ) if (hm->values[i] >= min && hm->values[i] <= max) count++; return count; } void TCOD_heightmap_scale(TCOD_heightmap_t *hm, float value) { int i; for (i=0; i < hm->w*hm->h; i++ ) hm->values[i]*=value; } void TCOD_heightmap_clamp(TCOD_heightmap_t *hm, float min, float max) { int i; for (i=0; i < hm->w*hm->h; i++ ) { hm->values[i]=CLAMP(min,max,hm->values[i]); } } void TCOD_heightmap_lerp_hm(const TCOD_heightmap_t *hm1, const TCOD_heightmap_t *hm2, TCOD_heightmap_t *hmres, float coef) { int i; if ( hm1->w != hm2->w || hm1->h != hm2->h || hm1->w != hmres->w || hm1->h != hmres->h ) { return; } for (i=0; i < hm1->w*hm1->h; i++ ) { hmres->values[i]=hm1->values[i]+(hm2->values[i]-hm1->values[i])*coef; } } void TCOD_heightmap_add_hm(const TCOD_heightmap_t *hm1, const TCOD_heightmap_t *hm2, TCOD_heightmap_t *hmres) { int i; if ( hm1->w != hm2->w || hm1->h != hm2->h || hm1->w != hmres->w || hm1->h != hmres->h ) { return; } for (i=0; i < hm1->w*hm1->h; i++ ) { hmres->values[i]=hm1->values[i]+hm2->values[i]; } } void TCOD_heightmap_multiply_hm(const TCOD_heightmap_t *hm1, const TCOD_heightmap_t *hm2, TCOD_heightmap_t *hmres) { int i; if ( hm1->w != hm2->w || hm1->h != hm2->h || hm1->w != hmres->w || hm1->h != hmres->h ) { return; } for (i=0; i < hm1->w*hm1->h; i++ ) { hmres->values[i]=hm1->values[i]*hm2->values[i]; } } float TCOD_heightmap_get_slope(const TCOD_heightmap_t *hm, int x, int y) { static int dix[8]={-1,0,1,-1,1,-1,0,1}; static int diy[8]={-1,-1,-1,0,0,1,1,1}; float mindy=0.0f,maxdy=0.0f; float v=GET_VALUE(hm,x,y); int i; for (i=0; i < 8; i++ ) { int nx=x+dix[i]; int ny=y+diy[i]; if ( nx >= 0 && nx < hm->w && ny >= 0 && ny < hm->h ) { float nslope=(GET_VALUE(hm,nx,ny)-v); if ( nslope > maxdy ) { maxdy=nslope; } else if ( nslope < mindy ) { mindy=nslope; } } } return (float)atan2(maxdy+mindy,1.0f); } void TCOD_heightmap_rain_erosion(TCOD_heightmap_t *hm, int nbDrops,float erosionCoef,float agregationCoef,TCOD_random_t rnd) { while ( nbDrops > 0 ) { int curx=TCOD_random_get_int(rnd,0,hm->w-1); int cury=TCOD_random_get_int(rnd,0,hm->h-1); static int dx[8]={-1,0,1,-1,1,-1,0,1}; static int dy[8]={-1,-1,-1,0,0,1,1,1}; float slope=0.0f; float sediment=0.0f; do { int nextx=0,nexty=0,i; float v=GET_VALUE(hm,curx,cury); /* calculate slope at x,y */ slope=0.0f; for (i=0; i < 8; i++ ) { int nx=curx+dx[i]; int ny=cury+dy[i]; if ( nx >= 0 && nx < hm->w && ny >= 0 && ny < hm->h ) { float nslope=v-GET_VALUE(hm,nx,ny); if ( nslope > slope ) { slope=nslope; nextx=nx; nexty=ny; } } } if ( slope > 0.0f ) { /* GET_VALUE(hm,curx,cury) *= 1.0f - (erosionCoef * slope); */ GET_VALUE(hm,curx,cury) -= erosionCoef * slope; curx=nextx; cury=nexty; sediment+=slope; } else { /* GET_VALUE(hm,curx,cury) *= 1.0f + (agregationCoef*sediment); */ GET_VALUE(hm,curx,cury) += agregationCoef*sediment; } } while ( slope > 0.0f ); nbDrops--; } } #if 0 static void setMPDHeight(TCOD_heightmap_t *hm, TCOD_random_t rnd,int x,int y, float z, float offset); static void setMDPHeightSquare(TCOD_heightmap_t *hm, TCOD_random_t rnd,int x, int y, int initsz, int sz,float offset); void TCOD_heightmap_heat_erosion(TCOD_heightmap_t *hm, int nbPass,float minSlope,float erosionCoef,float agregationCoef,TCOD_random_t rnd) { int x; while ( nbPass > 0 ) { for (x=0; x < hm->w; x++) { int offset=x,y; for (y=0; y < hm->h; y++) { static int dx[8]={-1,0,1,-1,1,-1,0,1}; static int dy[8]={-1,-1,-1,0,0,1,1,1}; int nextx=0,nexty=0,i; float v=hm->values[offset]; /* calculate slope at x,y */ float slope=0.0f; for (i=0; i < 8; i++ ) { /* 4 : von neumann neighbourhood 8 : moore neighbourhood */ int nx=x+dx[i]; int ny=y+dy[i]; if ( nx >= 0 && nx < hm->w && ny >= 0 && ny < hm->h ) { float nslope=v-GET_VALUE(hm,nx,ny); if ( nslope > slope ) { slope=nslope; nextx=nx; nexty=ny; } } } if ( slope > minSlope ) { GET_VALUE(hm,x,y) -= erosionCoef*(slope-minSlope); GET_VALUE(hm,nextx,nexty) += agregationCoef*(slope-minSlope); } offset+=hm->w; } } nbPass--; } } #endif void TCOD_heightmap_kernel_transform(TCOD_heightmap_t *hm, int kernelsize, const int *dx, const int *dy, const float *weight, float minLevel,float maxLevel) { int x,y; for (x=0; x < hm->w; x++) { int offset=x; for (y=0; y < hm->h; y++) { if ( hm->values[offset] >= minLevel && hm->values[offset] <= maxLevel ) { float val=0.0f; float totalWeight=0.0f; int i; for (i=0; i < kernelsize; i++ ) { int nx=x+dx[i]; int ny=y+dy[i]; if ( nx >= 0 && nx < hm->w && ny >= 0 && ny < hm->h ) { val+=weight[i]*GET_VALUE(hm,nx,ny); totalWeight+=weight[i]; } } hm->values[offset]=val/totalWeight; } offset+=hm->w; } } } void TCOD_heightmap_add_voronoi(TCOD_heightmap_t *hm, int nbPoints, int nbCoef, const float *coef,TCOD_random_t rnd) { typedef struct { int x,y; float dist; } point_t; point_t *pt; int i,x,y; if ( nbPoints <= 0 ) return; pt=(point_t *)malloc(sizeof(point_t)*nbPoints); for (i=0; i < nbPoints; i++ ) { pt[i].x = TCOD_random_get_int(rnd,0,hm->w-1); pt[i].y = TCOD_random_get_int(rnd,0,hm->h-1); } for (x=0; x < hm->w; x++) { int offset=x; for (y=0; y < hm->h; y++) { /* calculate distance to voronoi points */ for (i=0; i < nbPoints; i++ ) { pt[i].dist = (float)(pt[i].x-x)*(pt[i].x-x)+(pt[i].y-y)*(pt[i].y-y); } for (i=0; i < nbCoef; i++ ) { /* get closest point */ float minDist=1E8f; int idx=-1,j; for (j=0; j < nbPoints; j++ ) { if ( pt[j].dist < minDist ) { idx=j; minDist=pt[j].dist; } } hm->values[offset]+=coef[i]*pt[idx].dist; pt[idx].dist=1E8f; } offset+= hm->w; } } free(pt); } static void setMPDHeight(TCOD_heightmap_t *hm, TCOD_random_t rnd,int x,int y, float z, float offset); static void setMDPHeightSquare(TCOD_heightmap_t *hm, TCOD_random_t rnd,int x, int y, int initsz, int sz,float offset); void TCOD_heightmap_mid_point_displacement(TCOD_heightmap_t *hm, TCOD_random_t rnd, float roughness) { int step = 1; float offset = 1.0f; int initsz = MIN(hm->w,hm->h)-1; int sz = initsz; hm->values[0] = TCOD_random_get_float(rnd,0.0f,1.0f); hm->values[sz-1] = TCOD_random_get_float(rnd,0.0f,1.0f); hm->values[(sz-1)*sz] = TCOD_random_get_float(rnd,0.0f,1.0f); hm->values[sz*sz-1] = TCOD_random_get_float(rnd,0.0f,1.0f); while (sz > 0) { int x,y; /* diamond step */ for (x=0; x < step; x++ ) { for (y=0; y < step; y++ ) { int diamondx = sz / 2 + x * sz; int diamondy = sz / 2 + y * sz; float z= GET_VALUE(hm,x*sz,y*sz); z += GET_VALUE(hm,(x+1)*sz,y*sz); z += GET_VALUE(hm,(x+1)*sz,(y+1)*sz); z += GET_VALUE(hm,x*sz,(y+1)*sz); z *= 0.25f; setMPDHeight(hm,rnd,diamondx,diamondy,z,offset); } } offset*=roughness; /* square step */ for (x=0; x < step; x++ ) { for (y=0; y < step; y++ ) { int diamondx = sz / 2 + x * sz; int diamondy = sz / 2 + y * sz; /* north */ setMDPHeightSquare(hm, rnd, diamondx, diamondy-sz/2, initsz,sz/2, offset); /* south */ setMDPHeightSquare(hm, rnd, diamondx, diamondy+sz/2, initsz,sz/2, offset); /* west */ setMDPHeightSquare(hm, rnd, diamondx-sz/2, diamondy, initsz,sz/2, offset); /* east */ setMDPHeightSquare(hm, rnd, diamondx+sz/2, diamondy, initsz,sz/2, offset); } } sz /= 2; step *= 2; } } /* private stuff */ static void setMPDHeight(TCOD_heightmap_t *hm, TCOD_random_t rnd,int x,int y, float z, float offset) { z += TCOD_random_get_float(rnd,-offset,offset); GET_VALUE(hm,x,y)=z; } static void setMDPHeightSquare(TCOD_heightmap_t *hm, TCOD_random_t rnd,int x, int y, int initsz, int sz,float offset) { float z=0; int count=0; if ( y >= sz ) { z += GET_VALUE(hm,x,y-sz); count++; } if ( x >= sz ) { z += GET_VALUE(hm,x-sz,y); count++; } if ( y+sz < initsz ) { z += GET_VALUE(hm,x,y+sz); count++; } if ( x+sz < initsz ) { z += GET_VALUE(hm,x+sz,y); count++; } z /= count; setMPDHeight(hm,rnd,x,y,z,offset); } libtcod-1.6.4+dfsg/src/image.cpp000066400000000000000000000102661321276576200164560ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #ifdef TCOD_IMAGE_SUPPORT TCODImage::TCODImage(const char *filename) : deleteData(true) { data=(void *)TCOD_image_load(filename); } TCODImage::TCODImage(int width, int height) : deleteData(true) { data=(void *)TCOD_image_new(width,height); } #ifdef TCOD_CONSOLE_SUPPORT TCODImage::TCODImage(const TCODConsole *con) { data=(void *)TCOD_image_from_console(con->data); } #endif void TCODImage::clear(const TCODColor col) { TCOD_color_t ccol; ccol.r=col.r; ccol.g=col.g; ccol.b=col.b; TCOD_image_clear(data,ccol); } void TCODImage::getSize(int *w,int *h) const { TCOD_image_get_size(data,w,h); } TCODImage::~TCODImage() { if ( deleteData ) TCOD_image_delete(data); } TCODColor TCODImage::getPixel(int x, int y) const { return TCOD_image_get_pixel(data,x,y); } int TCODImage::getAlpha(int x,int y) const { return TCOD_image_get_alpha(data,x,y); } TCODColor TCODImage::getMipmapPixel(float x0,float y0, float x1, float y1) { return TCOD_image_get_mipmap_pixel(data,x0,y0,x1,y1); } void TCODImage::putPixel(int x, int y, const TCODColor col) { TCOD_color_t ccol = {col.r,col.g,col.b}; TCOD_image_put_pixel(data,x,y,ccol); } #ifdef TCOD_CONSOLE_SUPPORT void TCODImage::blit(TCODConsole *console, float x, float y, TCOD_bkgnd_flag_t bkgnd_flag, float scalex, float scaley, float angle) const { TCOD_image_blit(data,console->data,x,y,bkgnd_flag,scalex,scaley,angle); } void TCODImage::blitRect(TCODConsole *console, int x, int y, int w, int h, TCOD_bkgnd_flag_t bkgnd_flag) const { TCOD_image_blit_rect(data,console->data,x,y,w,h,bkgnd_flag); } #endif /* TCOD_CONSOLE_SUPPORT */ void TCODImage::save(const char *filename) const { TCOD_image_save(data,filename); } void TCODImage::setKeyColor(const TCODColor keyColor) { TCOD_color_t ccol = {keyColor.r,keyColor.g,keyColor.b}; TCOD_image_set_key_color(data,ccol); } bool TCODImage::isPixelTransparent(int x, int y) const { return TCOD_image_is_pixel_transparent(data,x,y) != 0; } #ifdef TCOD_CONSOLE_SUPPORT void TCODImage::refreshConsole(const TCODConsole *console) { TCOD_image_refresh_console(data,console->data); } #endif /* TCOD_CONSOLE_SUPPORT */ void TCODImage::invert() { TCOD_image_invert(data); } void TCODImage::hflip() { TCOD_image_hflip(data); } void TCODImage::rotate90(int numRotations) { TCOD_image_rotate90(data,numRotations); } void TCODImage::vflip() { TCOD_image_vflip(data); } void TCODImage::scale(int neww, int newh) { TCOD_image_scale(data,neww,newh); } #ifdef TCOD_CONSOLE_SUPPORT void TCODImage::blit2x(TCODConsole *dest, int dx, int dy, int sx, int sy, int w, int h) const { TCOD_image_blit_2x(data,dest->data,dx,dy,sx,sy,w,h); } #endif /* TCOD_CONSOLE_SUPPORT */ #endif /* TCOD_IMAGE_SUPPORT */libtcod-1.6.4+dfsg/src/image_c.c000066400000000000000000000661401321276576200164220ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #ifdef TCOD_IMAGE_SUPPORT #include #include #include #include #ifdef TCOD_CONSOLE_SUPPORT #include #endif #include #include typedef struct { int width,height; float fwidth,fheight; TCOD_color_t *buf; bool dirty; } mipmap_t; typedef struct { void *sys_img; int nb_mipmaps; mipmap_t *mipmaps; TCOD_color_t key_color; bool has_key_color; } image_data_t; /* Internal libtcod optimisation, direct colour manipulation in the images primary mipmap. */ TCOD_color_t *TCOD_image_get_colors(TCOD_image_t *image) { image_data_t *img = ((image_data_t *)image); return img->mipmaps[0].buf; } void TCOD_image_get_key_data(TCOD_image_t image, bool *has_key_color, TCOD_color_t *key_color) { image_data_t *img = ((image_data_t *)image); *has_key_color = img->has_key_color; *key_color = img->key_color; } void TCOD_image_invalidate_mipmaps(TCOD_image_t *image) { int i; image_data_t *img = ((image_data_t *)image); for (i = 1; i < img->nb_mipmaps; i++) { img->mipmaps[i].dirty = true; } } static int TCOD_image_get_mipmap_levels(int width, int height) { int curw=width; int curh=height; int nb_mipmap=0; while ( curw > 0 && curh > 0 ) { nb_mipmap++; curw >>= 1; curh >>= 1; } return nb_mipmap; } static void TCOD_image_generate_mip(image_data_t *img, int mip) { mipmap_t *orig=&img->mipmaps[0]; mipmap_t *cur =&img->mipmaps[mip]; int x,y; if (! cur->buf) { cur->buf=(TCOD_color_t *)calloc(sizeof(TCOD_color_t),cur->width*cur->height); } cur->dirty=false; for (x=0; x < cur->width; x++) { for (y=0; y < cur->height; y++) { int r=0,g=0,b=0, count=0; int sx,sy; TCOD_color_t *col; for (sx=(x << mip); sx < ((x+1)<width; count++; r+=orig->buf[offset].r; g+=orig->buf[offset].g; b+=orig->buf[offset].b; } } r /= count; g /= count; b /= count; col = &cur->buf[x+y*cur->width]; col->r=r; col->g=g; col->b=b; } } } /* Internal way of copying rendering fg/bg color frame data. */ bool TCOD_image_mipmap_copy_internal(TCOD_image_t srcImage, TCOD_image_t dstImage) { int i; image_data_t *img_src = (image_data_t *)srcImage; image_data_t *img_dst = (image_data_t *)dstImage; if (!img_src->mipmaps || img_src->sys_img || !img_dst->mipmaps || img_dst->sys_img) /* Both internal images. */ return false; if (img_src->mipmaps[0].width != img_dst->mipmaps[0].width || img_src->mipmaps[0].height != img_dst->mipmaps[0].height) return false; /* Copy all mipmaps? */ img_dst->mipmaps[0].dirty = img_src->mipmaps[0].dirty; memcpy(img_dst->mipmaps[0].buf, img_src->mipmaps[0].buf, sizeof(TCOD_color_t)*(img_src->mipmaps[0].width)*(img_src->mipmaps[0].height)); for (i = 1; i < img_src->nb_mipmaps; i++) img_dst->mipmaps[i].dirty = true; return true; } static void TCOD_image_init_mipmaps(image_data_t *img) { int w,h,i,x,y; float fw,fh; if (! img->sys_img ) return; TCOD_sys_get_image_size(img->sys_img,&w,&h); img->nb_mipmaps=TCOD_image_get_mipmap_levels(w,h); img->mipmaps = (mipmap_t *)calloc(sizeof(mipmap_t),img->nb_mipmaps); img->mipmaps[0].buf = (TCOD_color_t *)calloc(sizeof(TCOD_color_t),w*h); for (x=0; x < w; x++) { for (y=0;y < h; y++) { img->mipmaps[0].buf[x+y*w]=TCOD_sys_get_image_pixel(img->sys_img,x,y); } } fw=(float)w; fh=(float)h; for ( i=0; i < img->nb_mipmaps; i++) { img->mipmaps[i].width=w; img->mipmaps[i].height=h; img->mipmaps[i].fwidth=fw; img->mipmaps[i].fheight=fh; img->mipmaps[i].dirty=true; w >>= 1; h >>= 1; fw *= 0.5f; fh *= 0.5f; } img->mipmaps[0].dirty=false; } void TCOD_image_clear(TCOD_image_t image, TCOD_color_t color) { int i; image_data_t *img=(image_data_t *)image; if ( !img->mipmaps && !img->sys_img) return; /* no image data */ if ( ! img->mipmaps ) { TCOD_image_init_mipmaps(img); } for (i=0; i< img->mipmaps[0].width*img->mipmaps[0].height; i++) { img->mipmaps[0].buf[i] = color; } for ( i=1; i < img->nb_mipmaps; i++) { img->mipmaps[i].dirty=true; } } TCOD_image_t TCOD_image_new(int width, int height) { int i; float fw,fh; image_data_t *ret=(image_data_t *)calloc(sizeof(image_data_t),1); ret->nb_mipmaps=TCOD_image_get_mipmap_levels(width,height); ret->mipmaps = (mipmap_t *)calloc(sizeof(mipmap_t),ret->nb_mipmaps); ret->mipmaps[0].buf = (TCOD_color_t *)calloc(sizeof(TCOD_color_t),width*height); for (i=0; i< width*height; i++) { ret->mipmaps[0].buf[i] = TCOD_black; } fw=(float)width; fh=(float)height; for ( i=0; i < ret->nb_mipmaps; i++) { ret->mipmaps[i].width=width; ret->mipmaps[i].height=height; ret->mipmaps[i].fwidth=fw; ret->mipmaps[i].fheight=fh; width >>= 1; height >>= 1; fw *= 0.5f; fh *= 0.5f; } return (TCOD_image_t)ret; } TCOD_image_t TCOD_image_load(const char *filename) { image_data_t *ret=(image_data_t *)calloc(sizeof(image_data_t),1); ret->sys_img=TCOD_sys_load_image(filename); return (TCOD_image_t)ret; } void TCOD_image_get_size(TCOD_image_t image, int *w,int *h) { image_data_t *img=(image_data_t *)image; if ( !img->mipmaps && !img->sys_img) return; /* no image data */ if ( img->mipmaps ) { *w = img->mipmaps[0].width; *h = img->mipmaps[0].height; } else { TCOD_sys_get_image_size(img->sys_img,w,h); } } TCOD_color_t TCOD_image_get_pixel(TCOD_image_t image,int x, int y) { image_data_t *img=(image_data_t *)image; if ( !img->mipmaps && !img->sys_img) return TCOD_black; /* no image data */ if ( img->mipmaps ) { if ( x >= 0 && x < img->mipmaps[0].width && y >= 0 && y < img->mipmaps[0].height ) { return img->mipmaps[0].buf[x+y*img->mipmaps[0].width]; } else { return TCOD_black; } } else { return TCOD_sys_get_image_pixel(img->sys_img,x,y); } } int TCOD_image_get_alpha(TCOD_image_t image,int x, int y) { image_data_t *img=(image_data_t *)image; if ( img->sys_img ) { return TCOD_sys_get_image_alpha(img->sys_img,x,y); } else return 255; } TCOD_color_t TCOD_image_get_mipmap_pixel(TCOD_image_t image,float x0,float y0, float x1, float y1) { int texel_xsize,texel_ysize, texel_size, texel_x,texel_y; int cur_size=1; int mip=0; image_data_t *img=(image_data_t *)image; if ( !img->mipmaps && !img->sys_img) return TCOD_black; /* no image data */ if (!img->mipmaps) TCOD_image_init_mipmaps(img); texel_xsize=(int)(x1-x0); texel_ysize=(int)(y1-y0); texel_size=texel_xsize < texel_ysize ? texel_ysize : texel_xsize; while ( mip < img->nb_mipmaps-1 && cur_size < texel_size ) { mip++; cur_size <<= 1; } if ( mip > 0 ) mip --; texel_x=(int)(x0*(img->mipmaps[mip].width)/img->mipmaps[0].fwidth); texel_y=(int)(y0*(img->mipmaps[mip].height)/img->mipmaps[0].fheight); if (img->mipmaps[mip].buf == NULL || img->mipmaps[mip].dirty) { TCOD_image_generate_mip(img,mip); } if ( texel_x < 0 || texel_y < 0 || texel_x >= img->mipmaps[mip].width || texel_y >= img->mipmaps[mip].height ) return TCOD_black; return img->mipmaps[mip].buf[texel_x+texel_y*img->mipmaps[mip].width]; } void TCOD_image_put_pixel(TCOD_image_t image,int x, int y,TCOD_color_t col) { image_data_t *img=(image_data_t *)image; if ( !img->mipmaps && !img->sys_img) return; /* no image data */ if ( ! img->mipmaps ) { TCOD_image_init_mipmaps(img); } if ( x >= 0 && x < img->mipmaps[0].width && y >= 0 && y < img->mipmaps[0].height ) { int mip; img->mipmaps[0].buf[x+y*img->mipmaps[0].width] = col; for (mip=1; mip < img->nb_mipmaps; mip++) { img->mipmaps[mip].dirty=true; } } } void TCOD_image_delete_internal(TCOD_image_t image) { image_data_t *img=(image_data_t *)image; if ( img->mipmaps ) { int i; for ( i=0; i < img->nb_mipmaps; i++) { if ( img->mipmaps[i].buf ) free(img->mipmaps[i].buf); } free(img->mipmaps); } if ( img->sys_img ) { #ifdef TCOD_SDL2 TCOD_sys_delete_bitmap(img->sys_img); #endif } } void TCOD_image_delete(TCOD_image_t image) { TCOD_image_delete_internal(image); free(image); } bool TCOD_image_is_pixel_transparent(TCOD_image_t image, int x, int y) { image_data_t *img=(image_data_t *)image; TCOD_color_t col=TCOD_image_get_pixel(image,x,y); if ( img->has_key_color && img->key_color.r == col.r && img->key_color.g == col.g && img->key_color.b == col.b ) { return true; } if ( TCOD_image_get_alpha(image,x,y) == 0 ) return true; return false; } #ifdef TCOD_CONSOLE_SUPPORT void TCOD_image_blit(TCOD_image_t image, TCOD_console_t console, float x, float y, TCOD_bkgnd_flag_t bkgnd_flag, float scalex, float scaley, float angle) { int width,height; float rx,ry; image_data_t *img=(image_data_t *)image; if ( scalex == 0.0f || scaley == 0.0f || bkgnd_flag == TCOD_BKGND_NONE ) return; TCOD_image_get_size(image,&width,&height); rx = x - width * 0.5f; ry = y - height * 0.5f; if ( scalex == 1.0f && scaley == 1.0f && angle == 0.0f && rx == ((int)rx) && ry == ((int)ry)) { /* clip the image */ int ix = (int)(x - width*0.5f); int iy = (int)(y - height*0.5f); int minx=MAX(ix,0); int miny=MAX(iy,0); int maxx=MIN(ix+width,TCOD_console_get_width(console)); int maxy=MIN(iy+height,TCOD_console_get_height(console)); int offx=0,offy=0; int cx,cy; if ( ix < 0 ) offx=-ix; if ( iy < 0 ) offy=-iy; for (cx=minx; cx < maxx; cx ++) { for (cy=miny; cy < maxy; cy ++) { TCOD_color_t col=TCOD_image_get_pixel(image,cx-minx+offx,cy-miny+offy); if ( !img->has_key_color || img->key_color.r != col.r || img->key_color.g != col.g || img->key_color.b != col.b ) { TCOD_console_set_char_background(console,cx,cy,col,bkgnd_flag); } } } } else { float iw=width/2*scalex; float ih=height/2*scaley; /* get the coordinates of the image corners in the console */ float newx_x = (float)cos(angle); float newx_y = -(float)sin(angle); float newy_x = newx_y; float newy_y = -newx_x; float x0,y0,x1,y1,x2,y2,x3,y3; /* image corners coordinates */ int rx,ry,rw,rh; /* rectangular area in the console */ int cx,cy; int minx,miny,maxx,maxy; float invscalex,invscaley; /* 0 = P - w/2 x' +h/2 y' */ x0 = x-iw*newx_x+ih*newy_x; y0 = y-iw*newx_y+ih*newy_y; /* 1 = P + w/2 x' + h/2 y' */ x1 = x+iw*newx_x+ih*newy_x; y1 = y+iw*newx_y+ih*newy_y; /* 2 = P + w/2 x' - h/2 y' */ x2 = x+iw*newx_x-ih*newy_x; y2 = y+iw*newx_y-ih*newy_y; /* 3 = P - w/2 x' - h/2 y' */ x3 = x-iw*newx_x-ih*newy_x; y3 = y-iw*newx_y-ih*newy_y; /* get the affected rectangular area in the console */ rx=(int)(MIN(MIN(x0,x1),MIN(x2,x3))); ry=(int)(MIN(MIN(y0,y1),MIN(y2,y3))); rw=(int)(MAX(MAX(x0,x1),MAX(x2,x3))) - rx; rh=(int)(MAX(MAX(y0,y1),MAX(y2,y3))) - ry; /* clip it */ minx=MAX(rx,0); miny=MAX(ry,0); maxx=MIN(rx+rw,TCOD_console_get_width(console)); maxy=MIN(ry+rh,TCOD_console_get_height(console)); invscalex=1.0f / scalex; invscaley=1.0f / scaley; for (cx=minx; cx < maxx; cx ++) { for (cy=miny; cy < maxy; cy ++) { float ix,iy; TCOD_color_t col; /* map the console pixel to the image world */ ix = (iw+ (cx-x) * newx_x + (cy-y) *(-newy_x))*invscalex; iy = (ih + (cx-x) * (newx_y) - (cy-y)*newy_y)*invscaley; col = TCOD_image_get_pixel(image,(int)(ix),(int)(iy)); if ( !img->has_key_color || img->key_color.r != col.r || img->key_color.g != col.g || img->key_color.b != col.b ) { if ( scalex < 1.0f || scaley < 1.0f ) { col = TCOD_image_get_mipmap_pixel(image,ix,iy,ix+1.0f,iy+1.0f); } TCOD_console_set_char_background(console,cx,cy,col,bkgnd_flag); } } } } } void TCOD_image_blit_rect(TCOD_image_t image, TCOD_console_t console, int x, int y, int w, int h, TCOD_bkgnd_flag_t bkgnd_flag) { int width,height; float scalex,scaley; TCOD_image_get_size(image,&width,&height); if ( w == -1 ) w=width; if ( h == -1 ) h=height; if ( w <= 0 || h <= 0 || bkgnd_flag == TCOD_BKGND_NONE ) return; scalex = (float)(w)/width; scaley = (float)(h)/height; TCOD_image_blit(image,console,x+w*0.5f,y+h*0.5f,bkgnd_flag,scalex,scaley,0.0f); } TCOD_image_t TCOD_image_from_console(TCOD_console_t console) { image_data_t *ret; void *bitmap=TCOD_sys_create_bitmap_for_console(console); ret=(image_data_t *)calloc(sizeof(image_data_t),1); ret->sys_img=bitmap; TCOD_image_refresh_console((TCOD_image_t)ret,console); return (TCOD_image_t)ret; } void TCOD_image_refresh_console(TCOD_image_t image, TCOD_console_t console) { image_data_t *img=(image_data_t *)image; console = (console?console:TCOD_ctx.root); /* We're copying the state and clearing part of the copy, no need to delete/free. */ TCOD_sys_console_to_bitmap( img->sys_img, (TCOD_console_data_t*)console, NULL); } #endif /* TCOD_CONSOLE_SUPPORT */ void TCOD_image_save(TCOD_image_t image, const char *filename) { image_data_t *img=(image_data_t *)image; void *bitmap=NULL; bool must_free=false; if ( img->sys_img ) { bitmap=img->sys_img; } else if ( img->mipmaps ){ bitmap=TCOD_sys_create_bitmap(img->mipmaps[0].width, img->mipmaps[0].height, img->mipmaps[0].buf); must_free=true; } if (bitmap) { TCOD_sys_save_bitmap(bitmap, filename); if ( must_free ) { TCOD_sys_delete_bitmap(bitmap); } } } void TCOD_image_set_key_color(TCOD_image_t image, TCOD_color_t key_color) { image_data_t *img=(image_data_t *)image; img->has_key_color=true; img->key_color=key_color; } void TCOD_image_invert(TCOD_image_t image) { int i,mip; int width,height; image_data_t *img=(image_data_t *)image; if ( !img->mipmaps && !img->sys_img) return; /* no image data */ if ( ! img->mipmaps ) { TCOD_image_init_mipmaps(img); } TCOD_image_get_size(image,&width,&height); for (i=0; i< width*height; i++) { TCOD_color_t col=img->mipmaps[0].buf[i]; col.r=255-col.r; col.g=255-col.g; col.b=255-col.b; img->mipmaps[0].buf[i] = col; } for (mip=1; mip < img->nb_mipmaps; mip++) { img->mipmaps[mip].dirty=true; } } void TCOD_image_hflip(TCOD_image_t image) { int px,py; int width,height; TCOD_image_get_size(image,&width,&height); for (py = 0; py < height; py++ ) { for (px = 0; px < width/2; px++ ) { TCOD_color_t col1=TCOD_image_get_pixel(image,px,py); TCOD_color_t col2=TCOD_image_get_pixel(image,width-1-px,py); TCOD_image_put_pixel(image,px,py,col2); TCOD_image_put_pixel(image,width-1-px,py,col1); } } } void TCOD_image_vflip(TCOD_image_t image) { int px,py; int width,height; TCOD_image_get_size(image,&width,&height); for (px = 0; px < width; px++ ) { for (py = 0; py < height/2; py++ ) { TCOD_color_t col1=TCOD_image_get_pixel(image,px,py); TCOD_color_t col2=TCOD_image_get_pixel(image,px,height-1-py); TCOD_image_put_pixel(image,px,py,col2); TCOD_image_put_pixel(image,px,height-1-py,col1); } } } void TCOD_image_rotate90(TCOD_image_t image, int numRotations) { int px,py; int width,height; numRotations = numRotations % 4; if (numRotations == 0 ) return; if ( numRotations < 0 ) numRotations += 4; TCOD_image_get_size(image,&width,&height); if (numRotations == 1) { /* rotate 90 degrees */ TCOD_image_t newImg=TCOD_image_new(height,width); image_data_t *img=(image_data_t *)image; image_data_t *img2=(image_data_t *)newImg; for (px = 0; px < width; px++ ) { for (py = 0; py < height; py++ ) { TCOD_color_t col1=TCOD_image_get_pixel(image,px,py); TCOD_image_put_pixel(newImg,height-1-py,px,col1); } } TCOD_image_delete_internal(image); /* update img with the new image content */ img->mipmaps = img2->mipmaps; img->sys_img=NULL; img->nb_mipmaps=img2->nb_mipmaps; free(img2); } else if ( numRotations == 2 ) { /* rotate 180 degrees */ int maxy=height/2 + ((height & 1) == 1? 1 : 0 ); for (px = 0; px < width; px++ ) { for (py = 0; py < maxy; py++ ) { if ( py != height-1-py || px < width/2 ) { TCOD_color_t col1=TCOD_image_get_pixel(image,px,py); TCOD_color_t col2=TCOD_image_get_pixel(image,width-1-px,height-1-py); TCOD_image_put_pixel(image,px,py,col2); TCOD_image_put_pixel(image,width-1-px,height-1-py,col1); } } } } else if (numRotations == 3) { /* rotate 270 degrees */ TCOD_image_t newImg=TCOD_image_new(height,width); image_data_t *img=(image_data_t *)image; image_data_t *img2=(image_data_t *)newImg; for (px = 0; px < width; px++ ) { for (py = 0; py < height; py++ ) { TCOD_color_t col1=TCOD_image_get_pixel(image,px,py); TCOD_image_put_pixel(newImg,py,width-1-px,col1); } } TCOD_image_delete_internal(image); /* update img with the new image content */ img->mipmaps = img2->mipmaps; img->sys_img=NULL; img->nb_mipmaps=img2->nb_mipmaps; free(img2); } } void TCOD_image_scale(TCOD_image_t image, int neww, int newh) { image_data_t *img=(image_data_t *)image; int px,py; int width,height; image_data_t *newimg; TCOD_image_get_size(image,&width,&height); if ( neww==width && newh==height ) return; if ( neww == 0 || newh == 0 ) return; newimg=(image_data_t *)TCOD_image_new(neww,newh); if ( neww < width && newh < height ) { /* scale down image, using supersampling */ for (py = 0; py < newh; py++ ) { float y0 = (float)(py) * height / newh; float y0floor = (float)floor(y0); float y0weight = 1.0f - (y0 - y0floor); int iy0 = (int)y0floor; float y1 = (float)(py+1) * height / newh; float y1floor = (float)floor(y1-0.00001); float y1weight = (y1 - y1floor); int iy1 = (int)y1floor; for (px = 0; px < neww; px++ ) { TCOD_color_t col; float x0 = (float)(px) * width / neww; float x0floor = (float)floor(x0); float x0weight = 1.0f - (x0 - x0floor); int ix0 = (int)x0floor; float x1 = (float)(px+1) * width / neww; float x1floor = (float)floor(x1- 0.00001); float x1weight = (x1 - x1floor); int ix1 = (int)x1floor; float r=0,g=0,b=0,sumweight=0.0f; int srcx,srcy; /* left & right fractional edges */ for (srcy=(int)(y0+1); srcy < (int)y1; srcy++) { TCOD_color_t col_left=TCOD_image_get_pixel(image,ix0,srcy); TCOD_color_t col_right=TCOD_image_get_pixel(image,ix1,srcy); r += col_left.r * x0weight + col_right.r * x1weight; g += col_left.g * x0weight + col_right.g * x1weight; b += col_left.b * x0weight + col_right.b * x1weight; sumweight += x0weight+x1weight; } /* top & bottom fractional edges */ for (srcx = (int)(x0+1); srcx < (int)x1; srcx++) { TCOD_color_t col_top=TCOD_image_get_pixel(image,srcx,iy0); TCOD_color_t col_bottom=TCOD_image_get_pixel(image,srcx,iy1); r += col_top.r * y0weight + col_bottom.r * y1weight; g += col_top.g * y0weight + col_bottom.g * y1weight; b += col_top.b * y0weight + col_bottom.b * y1weight; sumweight += y0weight+y1weight; } /* center */ for (srcy=(int)(y0+1); srcy < (int)y1; srcy++) { for (srcx = (int)(x0+1); srcx < (int)x1; srcx++) { TCOD_color_t col=TCOD_image_get_pixel(image,srcx,srcy); r += col.r; g += col.g; b += col.b; sumweight += 1.0f; } } /* corners */ col=TCOD_image_get_pixel(image,ix0,iy0); r += col.r * (x0weight * y0weight); g += col.g * (x0weight * y0weight); b += col.b * (x0weight * y0weight); sumweight += x0weight * y0weight; col=TCOD_image_get_pixel(image,ix0,iy1); r += col.r * (x0weight * y1weight); g += col.g * (x0weight * y1weight); b += col.b * (x0weight * y1weight); sumweight += x0weight * y1weight; col=TCOD_image_get_pixel(image,ix1,iy1); r += col.r * (x1weight * y1weight); g += col.g * (x1weight * y1weight); b += col.b * (x1weight * y1weight); sumweight += x1weight * y1weight; col=TCOD_image_get_pixel(image,ix1,iy0); r += col.r * (x1weight * y0weight); g += col.g * (x1weight * y0weight); b += col.b * (x1weight * y0weight); sumweight += x1weight * y0weight; sumweight = 1.0f / sumweight; r = r*sumweight + 0.5f; g = g*sumweight + 0.5f; b = b*sumweight + 0.5f; col.r=(int)r; col.g=(int)g; col.b=(int)b; TCOD_image_put_pixel(newimg,px,py,col); } } } else { /* scale up image, using nearest neightbor */ for (py = 0; py < newh; py++ ) { int srcy = py * height / newh; for (px = 0; px < neww; px++ ) { int srcx = px * width / neww; TCOD_color_t col=TCOD_image_get_pixel(image,srcx,srcy); TCOD_image_put_pixel(newimg,px,py,col); } } } /* destroy old image */ TCOD_image_delete_internal(image); /* update img with the new image content */ img->mipmaps = newimg->mipmaps; img->sys_img=NULL; img->nb_mipmaps=newimg->nb_mipmaps; free(newimg); } /* distance between two colors */ int rgbdist(const TCOD_color_t *c1,const TCOD_color_t *c2) { int dr=(int)(c1->r)-c2->r; int dg=(int)(c1->g)-c2->g; int db=(int)(c1->b)-c2->b; return dr*dr+dg*dg+db*db; } void getPattern(TCOD_color_t desired[4], TCOD_color_t palette[2], int *nbCols, int *ascii) { /* adapted from Jeff Lait's code posted on r.g.r.d */ int flag=0; /* pixels have following flag values : X 1 2 4 flag indicates which pixels uses foreground color (palette[1]) */ static int flagToAscii[8] = { 0, TCOD_CHAR_SUBP_NE,TCOD_CHAR_SUBP_SW,-TCOD_CHAR_SUBP_DIAG,TCOD_CHAR_SUBP_SE, TCOD_CHAR_SUBP_E,-TCOD_CHAR_SUBP_N,-TCOD_CHAR_SUBP_NW }; int weight[2] = { 0, 0 }; int i; /* First colour trivial. */ palette[0] = desired[0]; /* Ignore all duplicates... */ for (i = 1; i < 4; i++) { if (desired[i].r != palette[0].r || desired[i].g != palette[0].g || desired[i].b != palette[0].b) break; } /* All the same. */ if (i == 4) { *nbCols=1; return; } weight[0] = i; /* Found a second colour... */ palette[1] = desired[i]; weight[1] = 1; flag |= 1<<(i-1); *nbCols = 2; /* remaining colours */ i++; while (i< 4) { if (desired[i].r == palette[0].r && desired[i].g == palette[0].g && desired[i].b == palette[0].b) { weight[0]++; } else if (desired[i].r == palette[1].r && desired[i].g == palette[1].g && desired[i].b == palette[1].b) { flag |= 1<<(i-1); weight[1]++; } else { /* Bah, too many colours, */ /* merge the two nearest */ int dist0i=rgbdist(&desired[i], &palette[0]); int dist1i=rgbdist(&desired[i], &palette[1]); int dist01=rgbdist(&palette[0],&palette[1]); if ( dist0i < dist1i ) { if ( dist0i <= dist01 ) { /* merge 0 and i */ palette[0]=TCOD_color_lerp(desired[i],palette[0],weight[0]/(1.0f+weight[0])); weight[0]++; } else { /* merge 0 and 1 */ palette[0]=TCOD_color_lerp(palette[0],palette[1],(float)(weight[1])/(weight[0]+weight[1])); weight[0]++; palette[1]=desired[i]; flag=1<<(i-1); } } else { if ( dist1i <= dist01 ) { /* merge 1 and i */ palette[1]=TCOD_color_lerp(desired[i],palette[1],weight[1]/(1.0f+weight[1])); weight[1]++; flag|=1<<(i-1); } else { /* merge 0 and 1 */ palette[0]=TCOD_color_lerp(palette[0],palette[1],(float)(weight[1])/(weight[0]+weight[1])); weight[0]++; palette[1]=desired[i]; flag=1<<(i-1); } } } i++; } *ascii=flagToAscii[flag]; } #ifdef TCOD_CONSOLE_SUPPORT void TCOD_image_blit_2x(TCOD_image_t image, TCOD_console_t con, int dx, int dy, int sx, int sy, int w, int h) { TCOD_color_t grid[4]; TCOD_color_t cols[2]; int nbCols; int width,height,ascii,cx,cy; TCOD_console_data_t *dat = con ? (TCOD_console_data_t *)(con) : TCOD_ctx.root; image_data_t *img=(image_data_t *)image; int maxx,maxy; TCOD_IFNOT(image != NULL && dat != NULL) return; TCOD_image_get_size(image,&width,&height); if ( w == -1 ) w=width; if ( h == -1 ) h=height; /* check that the sx,sy/w,h rectangle is inside the image */ TCOD_ASSERT(sx >= 0 && sy >= 0 && sx+w <= width && sy+h <= height); TCOD_IFNOT(w > 0 && h > 0) return; sx=MAX(0,sx); sy=MAX(0,sy); w = MIN(w,width-sx); h = MIN(h,height-sy); maxx=dx+w/2 <= dat->w ? w : (dat->w-dx)*2; maxy=dy+h/2 <= dat->h ? h : (dat->h-dy)*2; /* check that the image is not blitted outside the console */ TCOD_IFNOT(dx+maxx/2 >= 0 && dy+maxy/2 >= 0 && dx < dat->w && dy < dat->h) return; maxx+=sx; maxy+=sy; for (cx=sx; cx < maxx; cx += 2) { for (cy=sy; cy < maxy; cy += 2) { /* get the 2x2 super pixel colors from the image */ int conx=dx+(cx-sx)/2; int cony=dy+(cy-sy)/2; TCOD_color_t consoleBack=TCOD_console_get_char_background(con,conx,cony); grid[0]=TCOD_image_get_pixel(image,cx,cy); if ( img->has_key_color && grid[0].r == img->key_color.r && grid[0].g == img->key_color.g && grid[0].b == img->key_color.b) grid[0]=consoleBack; if ( cx < maxx-1 ) { grid[1]=TCOD_image_get_pixel(image,cx+1,cy); if ( img->has_key_color && grid[1].r == img->key_color.r && grid[1].g == img->key_color.g && grid[1].b == img->key_color.b) grid[1]=consoleBack; } else grid[1]=consoleBack; if ( cy < maxy-1 ) { grid[2]=TCOD_image_get_pixel(image,cx,cy+1); if ( img->has_key_color && grid[2].r == img->key_color.r && grid[2].g == img->key_color.g && grid[2].b == img->key_color.b) grid[2]=consoleBack; } else grid[2]=consoleBack; if ( cx < maxx-1 && cy < maxy-1 ) { grid[3]=TCOD_image_get_pixel(image,cx+1,cy+1); if ( img->has_key_color && grid[3].r == img->key_color.r && grid[3].g == img->key_color.g && grid[3].b == img->key_color.b) grid[3]=consoleBack; } else grid[3]=consoleBack; /* analyse color, posterize, get pattern */ getPattern(grid,cols,&nbCols,&ascii); if ( nbCols == 1 ) { /* single color */ TCOD_console_set_char_background(con,conx,cony,cols[0],TCOD_BKGND_SET); TCOD_console_set_char(con,conx,cony,' '); } else { if ( ascii >= 0 ) { TCOD_console_set_char_background(con,conx,cony,cols[0],TCOD_BKGND_SET); TCOD_console_set_char_foreground(con,conx,cony,cols[1]); TCOD_console_set_char(con,conx,cony,ascii); } else { /* negative ascii code means we need to invert back/fore colors */ TCOD_console_set_char_background(con,conx,cony,cols[1],TCOD_BKGND_SET); TCOD_console_set_char_foreground(con,conx,cony,cols[0]); TCOD_console_set_char(con,conx,cony,-ascii); } } } } } #endif /* TCOD_CONSOLE_SUPPORT */ #endif /* TCOD_IMAGE_SUPPORT */ libtcod-1.6.4+dfsg/src/lex.cpp000066400000000000000000000063301321276576200161610ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "lex.hpp" #include #include #include #include #include #include TCODLex::TCODLex( const char **_symbols, const char **_keywords, const char *simpleComment, const char *commentStart, const char *commentStop, const char *javadocCommentStart, const char *_stringDelim, int _flags) { data=(void *)TCOD_lex_new(_symbols,_keywords,simpleComment,commentStart,commentStop,javadocCommentStart,_stringDelim,_flags); } TCODLex::TCODLex() { data= (void *)TCOD_lex_new_intern(); } TCODLex::~TCODLex() { TCOD_lex_delete((TCOD_lex_t *)data); } char *TCODLex::getLastJavadoc() { return TCOD_lex_get_last_javadoc((TCOD_lex_t *)data); } void TCODLex::setDataBuffer(char *dat) { TCOD_lex_set_data_buffer((TCOD_lex_t *)data,dat); } bool TCODLex::setDataFile(const char *_filename) { return TCOD_lex_set_data_file((TCOD_lex_t *)data,_filename) != 0; } int TCODLex::parse() { return TCOD_lex_parse((TCOD_lex_t *)data); } int TCODLex::parseUntil(int tokenType) { return TCOD_lex_parse_until_token_type((TCOD_lex_t *)data,tokenType); } int TCODLex::parseUntil(const char *tokenValue) { return TCOD_lex_parse_until_token_value((TCOD_lex_t *)data,tokenValue); } void TCODLex::savepoint(TCODLex *savepoint) { TCOD_lex_savepoint((TCOD_lex_t *)data,(TCOD_lex_t *)(savepoint->data)); } void TCODLex::restore(TCODLex *savepoint) { TCOD_lex_restore((TCOD_lex_t *)data,(TCOD_lex_t *)(savepoint->data)); } bool TCODLex::expect(int tokenType) { return TCOD_lex_expect_token_type((TCOD_lex_t *)data,tokenType) != 0; } bool TCODLex::expect(int tokenType, const char *tokenValue) { return TCOD_lex_expect_token_value((TCOD_lex_t *)data,tokenType,tokenValue) != 0; } libtcod-1.6.4+dfsg/src/lex_c.c000066400000000000000000000420171321276576200161250ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #define MAX_JAVADOC_COMMENT_SIZE 16384 /* damn ANSI C does not know strdup, strcasecmp, strncasecmp */ char *TCOD_strdup(const char *s) { size_t l=strlen(s)+1; char *ret=malloc(sizeof(char)*l); memcpy(ret,s,sizeof(char)*l); return ret; } int TCOD_strcasecmp(const char *s1, const char *s2) { unsigned char c1,c2; do { c1 = *s1++; c2 = *s2++; c1 = (unsigned char) tolower( (unsigned char) c1); c2 = (unsigned char) tolower( (unsigned char) c2); } while((c1 == c2) && (c1 != '\0')); return (int) c1-c2; } int TCOD_strncasecmp(const char *s1, const char *s2, size_t n) { unsigned char c1,c2; do { c1 = *s1++; c2 = *s2++; c1 = (unsigned char) tolower( (unsigned char) c1); c2 = (unsigned char) tolower( (unsigned char) c2); n--; } while((c1 == c2) && (c1 != '\0') && n > 0); return (int) c1-c2; } static const char * TCOD_LEX_names[] = { "unknown token", "symbol", "keyword", "identifier", "string", "integer", "float", "char", "eof" }; static char *TCOD_last_error=NULL; const char *TCOD_lex_get_token_name(int token_type) { return TCOD_LEX_names[token_type]; } static void allocate_tok(TCOD_lex_t *lex, int len) { if ( lex->toklen > len ) return; while ( lex->toklen <= len ) lex->toklen *= 2; lex->tok = (char *)realloc(lex->tok,lex->toklen); } char *TCOD_lex_get_last_error(void) { return TCOD_last_error; } TCOD_lex_t *TCOD_lex_new_intern(void) { return (TCOD_lex_t *)calloc(1,sizeof(TCOD_lex_t)); } TCOD_lex_t * TCOD_lex_new( const char **_symbols, const char **_keywords, const char *simpleComment, const char *commentStart, const char *commentStop, const char *javadocCommentStart, const char *_stringDelim, int _flags) { TCOD_lex_t *lex=(TCOD_lex_t *)TCOD_lex_new_intern(); lex->flags = _flags; lex->last_javadoc_comment = (char *)calloc(sizeof(char),MAX_JAVADOC_COMMENT_SIZE ); if ( _symbols ) { while ( _symbols[ lex->nb_symbols ] ) { if ( strlen( _symbols[ lex->nb_symbols ] ) >= TCOD_LEX_SYMBOL_SIZE ) { static char msg[255]; sprintf (msg, "symbol '%s' too long (max size %d)", _symbols[ lex->nb_symbols ], TCOD_LEX_SYMBOL_SIZE ); TCOD_last_error=TCOD_strdup(msg); return NULL; } strcpy(lex->symbols[ lex->nb_symbols ], _symbols[ lex->nb_symbols ] ); lex->nb_symbols++; } } if ( _keywords ) { while ( _keywords[ lex->nb_keywords ] ) { if ( strlen( _keywords[ lex->nb_keywords ] ) >= TCOD_LEX_KEYWORD_SIZE ) { static char msg[255]; sprintf(msg,"keyword '%s' too long (max size %d)", _keywords[ lex->nb_keywords ], TCOD_LEX_KEYWORD_SIZE); TCOD_last_error=TCOD_strdup(msg); return NULL; } if ( lex->flags & TCOD_LEX_FLAG_NOCASE ) { char *ptr = (char *)_keywords[ lex->nb_keywords ]; while ( *ptr ) { *ptr = (char)toupper( *ptr); ptr++; } } strcpy(lex->keywords[ lex->nb_keywords ], _keywords[ lex->nb_keywords ] ); lex->nb_keywords++; } } lex->simpleCmt = simpleComment; lex->cmtStart = commentStart; lex->cmtStop = commentStop; lex->javadocCmtStart = javadocCommentStart; lex->stringDelim = _stringDelim; lex->lastStringDelim='\0'; lex->tok = (char *)calloc(sizeof(char),256); lex->toklen=256; return (TCOD_lex_t *)lex; } char *TCOD_lex_get_last_javadoc(TCOD_lex_t *lex) { if ( ! lex->javadoc_read && lex->last_javadoc_comment[0] != '\0' ) { lex->javadoc_read=true; return lex->last_javadoc_comment; } lex->javadoc_read=false; lex->last_javadoc_comment[0]='\0'; return NULL; } void TCOD_lex_delete(TCOD_lex_t *lex) { if ( ! lex->savept ) { if ( lex->filename ) free( lex->filename ); if ( lex->buf && lex->allocBuf ) free(lex->buf); if ( lex->last_javadoc_comment ) free(lex->last_javadoc_comment); } lex->filename=NULL; lex->buf = NULL; lex->allocBuf=false; if ( lex->tok ) free(lex->tok); free(lex); } void TCOD_lex_set_data_buffer_internal(TCOD_lex_t *lex) { lex->file_line = 1; lex->pos = lex->buf; lex->token_type = TCOD_LEX_UNKNOWN; lex->token_int_val = 0; lex->token_float_val = 0.0; lex->token_idx = -1; lex->tok[0] = '\0'; } void TCOD_lex_set_data_buffer(TCOD_lex_t *lex,char *dat) { lex->buf = dat; lex->allocBuf = false; TCOD_lex_set_data_buffer_internal(lex); } bool TCOD_lex_set_data_file(TCOD_lex_t *lex, const char *_filename) { FILE *f; char *ptr; long size; if ( ! _filename ) { TCOD_last_error = (char *)"Lex.setDatafile(NULL) called"; return false; } f = fopen( _filename, "rb" ); if ( f == NULL ) { static char msg[255]; sprintf(msg, "Cannot open '%s'", _filename); TCOD_last_error=TCOD_strdup(msg); return false; } fseek(f, 0, SEEK_END); size = ftell(f); fclose(f); f = fopen( _filename, "r" ); lex->buf = (char*)calloc(sizeof(char),(size + 1)); lex->filename = TCOD_strdup( _filename ); if ( lex->buf == NULL || lex->filename == NULL ) { fclose(f); if ( lex->buf ) free(lex->buf); if ( lex->filename ) { free( lex->filename ); } TCOD_last_error=(char *)"Out of memory"; return false; } ptr=lex->buf; /* can't rely on size to read because of MS/DOS dumb CR/LF handling */ while ( fgets(ptr, size,f ) ) { ptr += strlen(ptr); } fclose(f); TCOD_lex_set_data_buffer_internal(lex); lex->allocBuf=true; return true; } void TCOD_lex_get_new_line(TCOD_lex_t *lex) { if ( *(lex->pos) == '\n' ) { lex->file_line ++; lex->pos++; } } #ifdef TCOD_VISUAL_STUDIO #pragma warning(disable:4127) /* conditional expression is constant */ #endif int TCOD_lex_get_space(TCOD_lex_t *lex) { char c; char *startPos=NULL; while ( 1 ) { while ( (c = *lex->pos) <= ' ') { if (c=='\n') TCOD_lex_get_new_line(lex); else if (c == 0) return TCOD_LEX_EOF; /* end of file */ else lex->pos++; } if ( lex->simpleCmt && strncmp(lex->pos, lex->simpleCmt, strlen(lex->simpleCmt)) == 0 ) { if ( ! startPos ) startPos = lex->pos; while ( *lex->pos != '\0' && *lex->pos != '\n' ) lex->pos++; TCOD_lex_get_new_line(lex); continue; } if ( lex->cmtStart && lex->cmtStop && strncmp(lex->pos, lex->cmtStart, strlen(lex->cmtStart)) == 0 ) { int isJavadoc=( lex->javadocCmtStart && strncmp(lex->pos, lex->javadocCmtStart, strlen(lex->javadocCmtStart)) == 0 ); int cmtLevel=1; char *javadocStart = NULL; if ( ! startPos ) startPos = lex->pos; if ( isJavadoc ) { javadocStart=lex->pos+strlen(lex->javadocCmtStart); while ( isspace(*javadocStart) ) javadocStart++; } lex->pos++; do { if ( *lex->pos == '\n' ) { TCOD_lex_get_new_line(lex); } else lex->pos++; if ( *lex->pos == '\0' ) return TCOD_LEX_EOF; if ( (lex->flags & TCOD_LEX_FLAG_NESTING_COMMENT) && strncmp(lex->pos-1, lex->cmtStart, strlen(lex->cmtStart)) == 0) cmtLevel++; if ( strncmp(lex->pos-1, lex->cmtStop, strlen(lex->cmtStop)) == 0) cmtLevel--; } while ( cmtLevel > 0 ); lex->pos++; if ( isJavadoc ) { char *src, *dst; char *end = lex->pos - strlen(lex->cmtStop); while ( isspace(*end) && end > javadocStart ) end --; src = javadocStart; dst = lex->last_javadoc_comment; while ( src < end ) { /* skip heading spaces */ while ( src < end && isspace(*src) && *src != '\n') src ++; /* copy comment line */ while ( src < end && *src != '\n' ) *dst++ = *src++; if ( *src == '\n' ) *dst++ = *src++; } /* remove trailing spaces */ while ( dst > lex->last_javadoc_comment && isspace (*(dst-1)) ) dst --; *dst = '\0'; lex->javadoc_read=false; } continue; } break; } if ( (lex->flags & TCOD_LEX_FLAG_TOKENIZE_COMMENTS) && startPos && lex->pos > startPos ) { int len = (int)(lex->pos - startPos); allocate_tok(lex, len+1); strncpy(lex->tok,startPos,len); lex->tok[len]=0; lex->token_type = TCOD_LEX_COMMENT; lex->token_idx = -1; return TCOD_LEX_COMMENT; } return TCOD_LEX_UNKNOWN; } int TCOD_lex_hextoint(char c) { int v=toupper(c); if ( v >= '0' && v <= '9' ) return v-'0'; return 10 + (v-'A'); } static bool TCOD_lex_get_special_char(TCOD_lex_t *lex, char *c) { *c = *(++(lex->pos) ); switch ( *c ) { case 'n' : *c='\n'; break; case 't' : *c='\t'; break; case 'r' : *c='\r'; break; case '\\' : case '\"' : case '\'' : break; case 'x' : { /* hexadecimal value "\x80" */ int value=0; bool hasHex=false; *c = *(++(lex->pos) ); while (( *c >= '0' && *c <= '9' ) || (*c >= 'a' && *c <= 'f') || (*c >= 'A' && *c <= 'F') ) { hasHex=true; value <<= 4; value += TCOD_lex_hextoint(*c); *c = *(++(lex->pos) ); } if (! hasHex ) { TCOD_last_error=(char *)"\\x must be followed by an hexadecimal value"; return false; } *c = value; lex->pos--; } break; case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : { /* octal value "\200" */ int value=0; while ( *c >= '0' && *c <= '7' ) { value <<= 3; value += (*c - '0'); *c = *(++(lex->pos) ); } *c = value; lex->pos--; } break; default : TCOD_last_error=(char *)"bad escape sequence inside quote"; return false; } return true; } int TCOD_lex_get_string(TCOD_lex_t *lex) { char c; int len = 0; do { c= *(++(lex->pos)); if ( c == '\0' ) { TCOD_last_error=(char *)"EOF inside quote"; return TCOD_LEX_ERROR; } if ( c == '\n' ) { TCOD_last_error=(char *)"newline inside quote"; return TCOD_LEX_ERROR; } if ( c== '\\' ) { if ( ! TCOD_lex_get_special_char(lex,&c) ) return TCOD_LEX_ERROR; } else if ( c == lex->lastStringDelim ) { allocate_tok(lex, len); lex->tok[ len ] = '\0'; lex->token_type = TCOD_LEX_STRING; lex->token_idx = -1; lex->pos++; return TCOD_LEX_STRING; } allocate_tok(lex, len); lex->tok[ len++ ] = c; } while ( 1 ); } #ifdef TCOD_VISUAL_STUDIO #pragma warning(default:4127) /* conditional expression is constant */ #endif int TCOD_lex_get_number(TCOD_lex_t *lex) { int c; int len; char *ptr; int bhex = 0, bfloat = 0; len = 0; if ( *lex->pos == '-' ) { allocate_tok(lex, len); lex->tok[ len ++ ] = '-'; lex->pos++; } c = toupper(*lex->pos); if ( c == '0' && ( lex->pos[1] == 'x' || lex->pos[1]=='X') ) { bhex = 1; allocate_tok(lex, len); lex->tok[ len ++ ] = '0'; lex->pos++; c = toupper( * (lex->pos)); } do { allocate_tok(lex, len); lex->tok[ len++ ] = (char)c; lex->pos++; if ( c == '.' ) { if ( bhex ) { TCOD_last_error=(char *)"bad constant format"; return TCOD_LEX_ERROR; } bfloat = 1; } c = toupper(*lex->pos); } while ((c >= '0' && c<= '9') || ( bhex && c >= 'A' && c <= 'F' ) || c == '.' ); allocate_tok(lex, len); lex->tok[len] = 0; if ( !bfloat ) { lex->token_int_val = strtol( lex->tok, &ptr, 0 ); lex->token_float_val = (float)lex->token_int_val; lex->token_type = TCOD_LEX_INTEGER; lex->token_idx = -1; return TCOD_LEX_INTEGER; } else { lex->token_float_val = (float)atof( lex->tok ); lex->token_type = TCOD_LEX_FLOAT; lex->token_idx = -1; return TCOD_LEX_FLOAT; } } int TCOD_lex_get_char(TCOD_lex_t *lex) { char c; c= *(++(lex->pos)); if ( c == '\0' ) { TCOD_last_error=(char *)"EOF inside simple quote"; return TCOD_LEX_ERROR; } if ( c == '\n' ) { TCOD_last_error=(char *)"newline inside simple quote"; return TCOD_LEX_ERROR; } if ( c== '\\' ) { if ( ! TCOD_lex_get_special_char(lex,&c) ) return TCOD_LEX_ERROR; lex->pos++; } else lex->pos++; if ( *lex->pos != '\'' ) { TCOD_last_error= (char *)"bad character inside simple quote" ; return TCOD_LEX_ERROR; } lex->pos ++; lex->tok[ 0 ] = c; lex->tok[ 1 ] = '\0'; lex->token_type = TCOD_LEX_CHAR; lex->token_int_val = (int)c; lex->token_idx = -1; return TCOD_LEX_CHAR; } int TCOD_lex_get_symbol(TCOD_lex_t *lex) { int symb = 0; static char msg[255]; while ( symb < lex->nb_symbols ) { if ( ( ( lex->flags & TCOD_LEX_FLAG_NOCASE ) && TCOD_strncasecmp( lex->symbols[ symb ], lex->pos, strlen( lex->symbols[ symb ] ) ) == 0 ) || ( strncmp( lex->symbols[ symb ], lex->pos, strlen( lex->symbols[ symb ] ) ) == 0 ) ) { strcpy( lex->tok, lex->symbols[ symb ] ); lex->pos += strlen( lex->symbols[ symb ] ); lex->token_idx = symb; lex->token_type = TCOD_LEX_SYMBOL; return TCOD_LEX_SYMBOL; } symb ++; } lex->pos++; sprintf(msg, "unknown symbol %.10s", lex->pos-1 ); TCOD_last_error=TCOD_strdup(msg); return TCOD_LEX_ERROR; } int TCOD_lex_get_iden(TCOD_lex_t *lex) { char c = *lex->pos; int len = 0, key = 0; do { allocate_tok(lex, len); lex->tok[ len++ ] = c; c = *( ++ (lex->pos) ); } while ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) || ( c >= '0' && c <= '9' ) || c == '_' ); allocate_tok(lex, len); lex->tok[len ] = 0; while ( key < lex->nb_keywords ) { if ( strcmp( lex->tok, lex->keywords[ key ] ) == 0 || ( lex->flags & TCOD_LEX_FLAG_NOCASE && TCOD_strcasecmp( lex->tok, lex->keywords[ key ] ) == 0 )) { lex->token_type = TCOD_LEX_KEYWORD; lex->token_idx = key; return TCOD_LEX_KEYWORD; } key ++; } lex->token_type = TCOD_LEX_IDEN; lex->token_idx = -1; return TCOD_LEX_IDEN; } int TCOD_lex_parse(TCOD_lex_t *lex) { char *ptr; int token; token = TCOD_lex_get_space(lex); if ( token == TCOD_LEX_ERROR ) return token; ptr = lex->pos; if ( token != TCOD_LEX_UNKNOWN ) { lex->token_type = token; return token; } if ( strchr(lex->stringDelim, *ptr) ) { lex->lastStringDelim=*ptr; return TCOD_lex_get_string(lex); } if ( *ptr == '\'' ) { return TCOD_lex_get_char(lex); } if ( isdigit( (int)(*ptr) ) || ( *ptr == '-' && isdigit( (int)(ptr[1]) ) ) ) { return TCOD_lex_get_number(lex); } if ( ( *ptr >= 'a' && *ptr <= 'z' ) || ( *ptr >= 'A' && *ptr <= 'Z' ) || *ptr == '_' ) { return TCOD_lex_get_iden(lex); } return TCOD_lex_get_symbol(lex); } int TCOD_lex_parse_until_token_type(TCOD_lex_t *lex,int tokenType) { int token; token = TCOD_lex_parse(lex); if ( token == TCOD_LEX_ERROR ) return token; while ( token != TCOD_LEX_EOF ) { if ( token == tokenType ) return token; token = TCOD_lex_parse(lex); if ( token == TCOD_LEX_ERROR ) return token; } return token; } int TCOD_lex_parse_until_token_value(TCOD_lex_t *lex, const char *tokenValue) { int token; token = TCOD_lex_parse(lex); if ( token == TCOD_LEX_ERROR ) return token; { while ( token != TCOD_LEX_EOF ) if ( strcmp( lex->tok, tokenValue ) == 0 || ( ( lex->flags & TCOD_LEX_FLAG_NOCASE ) && TCOD_strcasecmp(lex->tok, tokenValue ) == 0 ) ) return token; token = TCOD_lex_parse(lex); if ( token == TCOD_LEX_ERROR ) return token; } return token; } void TCOD_lex_savepoint(TCOD_lex_t *lex,TCOD_lex_t *_savept) { TCOD_lex_t *savept=(TCOD_lex_t *)_savept; *savept = *lex; savept->tok = (char *)calloc(sizeof(char),lex->toklen); strcpy(savept->tok,lex->tok); savept->savept=true; } void TCOD_lex_restore(TCOD_lex_t *lex,TCOD_lex_t *_savept) { TCOD_lex_t *savept=(TCOD_lex_t *)_savept; *lex = *savept; lex->savept=false; } bool TCOD_lex_expect_token_type(TCOD_lex_t *lex,int token_type) { return (TCOD_lex_parse(lex) == token_type); } bool TCOD_lex_expect_token_value(TCOD_lex_t *lex,int token_type, const char *token_value) { TCOD_lex_parse(lex); return (token_type == lex->token_type && strcmp(lex->tok, token_value) == 0 ); } libtcod-1.6.4+dfsg/src/list_c.c000066400000000000000000000144101321276576200163040ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include /* calloc */ #include /* NULL/memcpy */ #include #define LIST(l) ((TCOD_list_int_t *)l) typedef struct { void **array; int fillSize; int allocSize; } TCOD_list_int_t; static void TCOD_list_allocate_int(TCOD_list_t l) { void **newArray; int newSize = LIST(l)->allocSize * 2; if ( newSize == 0 ) newSize = 16; newArray = (void **)calloc(sizeof(void *),newSize ); if ( LIST(l)->array ) { if ( LIST(l)->fillSize > 0 ) memcpy(newArray, LIST(l)->array, sizeof(void *)*LIST(l)->fillSize); free(LIST(l)->array); } LIST(l)->array=newArray; LIST(l)->allocSize=newSize; } void TCOD_list_set_size(TCOD_list_t l, int size) { LIST(l)->fillSize=MIN(size,LIST(l)->allocSize); } TCOD_list_t TCOD_list_new(void) { return (TCOD_list_t)calloc(1,sizeof(TCOD_list_int_t)); } TCOD_list_t TCOD_list_allocate(int nb_elements) { TCOD_list_t l=TCOD_list_new(); LIST(l)->array = (void **)calloc(sizeof(void *),nb_elements); LIST(l)->allocSize = nb_elements; return l; } TCOD_list_t TCOD_list_duplicate(TCOD_list_t l) { int i=0; void **t; TCOD_list_int_t *ret=(TCOD_list_int_t *)TCOD_list_new(); while ( ret->allocSize < LIST(l)->allocSize ) TCOD_list_allocate_int((TCOD_list_t)ret); ret->fillSize=LIST(l)->fillSize; for (t=TCOD_list_begin(l); t != TCOD_list_end(l); t++) { ret->array[i++]=*t; } return (TCOD_list_t)ret; } void TCOD_list_delete(TCOD_list_t l) { if ( l ) { if ( LIST(l)->array ) free(LIST(l)->array); free(l); } } void TCOD_list_push(TCOD_list_t l, const void * elt) { if ( LIST(l)->fillSize+1 >= LIST(l)->allocSize ) TCOD_list_allocate_int(l); LIST(l)->array[LIST(l)->fillSize++] = (void *)elt; } void * TCOD_list_pop(TCOD_list_t l) { if ( LIST(l)->fillSize == 0 ) return NULL; return LIST(l)->array[--(LIST(l)->fillSize)]; } void * TCOD_list_peek(TCOD_list_t l) { if ( LIST(l)->fillSize == 0 ) return NULL; return LIST(l)->array[LIST(l)->fillSize-1]; } void TCOD_list_add_all(TCOD_list_t l, TCOD_list_t l2) { void **curElt; for ( curElt = TCOD_list_begin(l2); curElt != TCOD_list_end(l2); curElt ++) { TCOD_list_push(l,*curElt); } } void * TCOD_list_get(TCOD_list_t l,int idx) { return LIST(l)->array[idx]; } void TCOD_list_set(TCOD_list_t l,const void *elt, int idx) { if ( idx < 0 ) return; while ( LIST(l)->allocSize < idx+1 ) TCOD_list_allocate_int(l); LIST(l)->array[idx]=(void *)elt; if ( idx+1 > LIST(l)->fillSize ) LIST(l)->fillSize = idx+1; } void ** TCOD_list_begin(TCOD_list_t l) { if ( LIST(l)->fillSize == 0 ) return (void **)NULL; return &LIST(l)->array[0]; } void ** TCOD_list_end(TCOD_list_t l) { if ( LIST(l)->fillSize == 0 ) return (void **)NULL; return &LIST(l)->array[LIST(l)->fillSize]; } void TCOD_list_reverse(TCOD_list_t l) { void **head=TCOD_list_begin(l); void **tail=TCOD_list_end(l) - 1; while ( head < tail ) { void *tmp=*head; *head=*tail; *tail=tmp; head++; tail--; } } void **TCOD_list_remove_iterator(TCOD_list_t l, void **elt) { void **curElt; for ( curElt = elt; curElt < TCOD_list_end(l)-1; curElt ++) { *curElt = *(curElt+1); } LIST(l)->fillSize--; if ( LIST(l)->fillSize == 0 ) return ((void **)NULL)-1; else return elt-1; } void TCOD_list_remove(TCOD_list_t l, const void * elt) { void **curElt; for ( curElt = TCOD_list_begin(l); curElt != TCOD_list_end(l); curElt ++) { if ( *curElt == elt ) { TCOD_list_remove_iterator(l,curElt); return; } } } void **TCOD_list_remove_iterator_fast(TCOD_list_t l, void **elt) { *elt = LIST(l)->array[LIST(l)->fillSize-1]; LIST(l)->fillSize--; if ( LIST(l)->fillSize == 0 ) return ((void **)NULL)-1; else return elt-1; } void TCOD_list_remove_fast(TCOD_list_t l, const void * elt) { void **curElt; for ( curElt = TCOD_list_begin(l); curElt != TCOD_list_end(l); curElt ++) { if ( *curElt == elt ) { TCOD_list_remove_iterator_fast(l,curElt); return; } } } bool TCOD_list_contains(TCOD_list_t l,const void * elt) { void **curElt; for ( curElt = TCOD_list_begin(l); curElt != TCOD_list_end(l); curElt ++) { if ( *curElt == elt ) return true; } return false; } void TCOD_list_clear(TCOD_list_t l) { LIST(l)->fillSize=0; } void TCOD_list_clear_and_delete(TCOD_list_t l) { void **curElt; for ( curElt = TCOD_list_begin(l); curElt != TCOD_list_end(l); curElt ++ ) { free(*curElt); } LIST(l)->fillSize=0; } int TCOD_list_size(TCOD_list_t l) { return LIST(l)->fillSize; } void **TCOD_list_insert_before(TCOD_list_t l,const void *elt,int before) { int idx; if ( LIST(l)->fillSize+1 >= LIST(l)->allocSize ) TCOD_list_allocate_int(l); for (idx=LIST(l)->fillSize; idx > before; idx--) { LIST(l)->array[idx]=LIST(l)->array[idx-1]; } LIST(l)->array[before]=(void *)elt; LIST(l)->fillSize++; return &LIST(l)->array[before]; } bool TCOD_list_is_empty(TCOD_list_t l) { return ( LIST(l)->fillSize == 0 ); } libtcod-1.6.4+dfsg/src/mersenne.cpp000066400000000000000000000044501321276576200172060ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include static TCODRandom *instance=(TCODRandom *)NULL; TCODRandom *TCODRandom::getInstance(void) { if (! instance ) { instance=new TCODRandom(TCOD_RNG_CMWC,true); } return instance; } TCODRandom::TCODRandom(TCOD_random_algo_t algo, bool allocate) { if ( allocate ) data = TCOD_random_new(algo); } TCODRandom::TCODRandom(uint32_t seed, TCOD_random_algo_t algo) { data=TCOD_random_new_from_seed(algo, seed); } TCODRandom::~TCODRandom() { TCOD_random_delete(data); } TCODRandom *TCODRandom::save() const { TCODRandom *ret=new TCODRandom(((mersenne_data_t *)data)->algo,false); ret->data=TCOD_random_save(data); return ret; } void TCODRandom::restore(const TCODRandom *backup) { TCOD_random_restore(data,backup->data); } libtcod-1.6.4+dfsg/src/mersenne_c.c000066400000000000000000000445631321276576200171610ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include static TCOD_random_t instance=NULL; static float rand_div=1.0f/(float)(0xffffffff); static double rand_div_double = 1.0 / (double)(0xffffffff); /* initialize the mersenne twister array */ static void mt_init(uint32_t seed, uint32_t mt[624] ) { int i; mt[0]= seed; for (i=1; i<624; i++) { mt[i] = (1812433253 * (mt[i-1] ^ (mt[i-1] >> 30)) + i); } } /* get the next random value from the mersenne twister array */ static uint32_t mt_rand(uint32_t mt[624], int *cur_mt) { #define MT_HIGH_BIT 0x80000000UL #define MT_LOW_BITS 0x7fffffffUL uint32_t y; if (*cur_mt == 624) { /* our 624 sequence is finished. generate a new one */ int i; for (i=0;i<623;i++) { y = ( mt[i] & MT_HIGH_BIT ) | ( mt[i+1] & MT_LOW_BITS ); if ( y & 1 ) { /* odd y */ mt[i] = mt[ (i + 397) % 624 ] ^ (y >> 1) ^ 2567483615UL; } else { /* even y */ mt[i] = mt[ (i + 397) % 624 ] ^ (y >> 1); } } y = ( mt[623] & MT_HIGH_BIT ) | ( mt[0] & MT_LOW_BITS ); if ( y & 1 ) { /* odd y */ mt[623] = mt[396] ^ (y >> 1) ^ 2567483615UL; } else { mt[623] = mt[396] ^ (y >> 1); } *cur_mt = 0; } y = mt[(*cur_mt)++]; y ^= (y >> 11); y ^= (y << 7) & 2636928640UL; y ^= (y << 15) & 4022730752UL; y ^= (y >> 18); return y; } /* get a random float between 0 and 1 */ static float frandom01(mersenne_data_t *r) { return (float)mt_rand(r->mt,&r->cur_mt)*rand_div; } /* string hashing function */ /* not used (yet) static uint32_t hash(const char *data,int len) { uint32_t hash = 0; uint32_t x; int i; for(i = 0; i < len; data++, i++) { hash = (hash << 4) + (*data); if((x = hash & 0xF0000000L) != 0) { hash ^= (x >> 24); hash &= ~x; } } return (hash & 0x7FFFFFFF); } */ /* get a random number from the CMWC */ #define CMWC_GET_NUMBER(num) { unsigned long long t; uint32_t x; r->cur=(r->cur+1)&4095; t=18782LL*r->Q[r->cur]+r->c; r->c=(t>>32); x=(uint32_t)(t+r->c); if (x < r->c) { x++; r->c++; } if((x+1)==0) { r->c++; x=0; } num = (uint32_t)(r->Q[r->cur] = 0xfffffffe - x); } TCOD_random_t TCOD_random_new(TCOD_random_algo_t algo) { return TCOD_random_new_from_seed(algo,(uint32_t)time(0)); } TCOD_random_t TCOD_random_get_instance(void) { if (! instance ) { instance=TCOD_random_new(TCOD_RNG_CMWC); } return instance; } TCOD_random_t TCOD_random_new_from_seed(TCOD_random_algo_t algo, uint32_t seed) { mersenne_data_t *r = (mersenne_data_t *)calloc(sizeof(mersenne_data_t),1); /* Mersenne Twister */ if (algo == TCOD_RNG_MT) { r->algo = TCOD_RNG_MT; r->cur_mt=624; mt_init(seed,r->mt); } /* Complementary-Multiply-With-Carry or Generalised Feedback Shift Register */ else { int i; /* fill the Q array with pseudorandom seeds */ uint32_t s = seed; for (i = 0; i < 4096; i++) r->Q[i] = s = (s * 1103515245) + 12345; /* glibc LCG */ r->c = ((s * 1103515245) + 12345) % 809430660; /* this max value is recommended by George Marsaglia */ r->cur = 0; r->algo = TCOD_RNG_CMWC; } r->distribution = TCOD_DISTRIBUTION_LINEAR; return (TCOD_random_t)r; } int TCOD_random_get_i(TCOD_random_t mersenne, int min, int max) { mersenne_data_t *r; int delta; if (max==min) return min; else if (max < min) { int tmp=max; max=min; min=tmp; } if (!mersenne) mersenne=TCOD_random_get_instance(); r=(mersenne_data_t *)mersenne; delta = max - min + 1; /* return a number from the Mersenne Twister */ if (r->algo == TCOD_RNG_MT) return ( mt_rand(r->mt,&r->cur_mt) % delta ) + min; /* or from the CMWC */ else { uint32_t number; CMWC_GET_NUMBER(number) return number % delta + min; } } float TCOD_random_get_f(TCOD_random_t mersenne,float min, float max) { mersenne_data_t *r; float delta,f; if (max==min) return min; else if (max < min) { float tmp=max; max=min; min=tmp; } if (!mersenne) mersenne=TCOD_random_get_instance(); r=(mersenne_data_t *)mersenne; delta = max - min; /* Mersenne Twister */ if (r->algo == TCOD_RNG_MT) f = delta * frandom01(r); /* CMWC */ else { uint32_t number; CMWC_GET_NUMBER(number) f = (float)(number) * rand_div * delta; } return min + f; } double TCOD_random_get_d(TCOD_random_t mersenne, double min, double max) { mersenne_data_t *r; double delta,f; if (max==min) return min; else if (max < min) { double tmp=max; max=min; min=tmp; } if (!mersenne) mersenne=TCOD_random_get_instance(); r=(mersenne_data_t *)mersenne; delta = max - min; /* Mersenne Twister */ if (r->algo == TCOD_RNG_MT) f = delta * (double)frandom01(r); /* CMWC */ else { uint32_t number; CMWC_GET_NUMBER(number) f = (double)(number) * rand_div_double * delta; } return min + f; } void TCOD_random_delete(TCOD_random_t mersenne) { TCOD_IFNOT(mersenne != NULL) return; if ( mersenne == instance ) instance = NULL; free(mersenne); } TCOD_random_t TCOD_random_save(TCOD_random_t mersenne) { mersenne_data_t *ret=(mersenne_data_t *)malloc(sizeof(mersenne_data_t)); if (!mersenne) mersenne=TCOD_random_get_instance(); memcpy(ret,mersenne,sizeof(mersenne_data_t)); return (TCOD_random_t)ret; } void TCOD_random_restore(TCOD_random_t mersenne, TCOD_random_t backup) { if (!mersenne) mersenne=TCOD_random_get_instance(); memcpy(mersenne,backup,sizeof(mersenne_data_t)); } /* Box-Muller transform (Gaussian distribution) */ double TCOD_random_get_gaussian_double (TCOD_random_t mersenne, double mean, double std_deviation) { double x1, x2, w, y1; static double y2; static bool again = false; double ret; if (again) ret = mean + y2 * std_deviation; else { mersenne_data_t *r = NULL; if (!mersenne) mersenne=TCOD_random_get_instance(); r = (mersenne_data_t *)mersenne; /* MT */ if (r->algo == TCOD_RNG_MT) { do { x1 = frandom01(r) * 2.0 - 1.0; x2 = frandom01(r) * 2.0 - 1.0; w = x1 * x1 + x2 * x2; } while (w >= 1.0); } /* CMWC */ else { uint32_t number; do { CMWC_GET_NUMBER(number) x1 = number * rand_div_double * 2.0 - 1.0; CMWC_GET_NUMBER(number) x2 = number * rand_div_double * 2.0 - 1.0; w = x1 * x1 + x2 * x2; } while (w >= 1.0); } w = sqrt((-2.0 * log(w)) / w); y1 = x1 * w; y2 = x2 * w; ret = mean + y1 * std_deviation; } again = !again; return ret; } float TCOD_random_get_gaussian_float (TCOD_random_t mersenne, float mean, float std_deviation) { return (float)TCOD_random_get_gaussian_double(mersenne, (double)mean, (double)std_deviation); } int TCOD_random_get_gaussian_int (TCOD_random_t mersenne, int mean, int std_deviation) { double num = TCOD_random_get_gaussian_double(mersenne,(double)mean,(double)std_deviation); return (num >= 0.0 ? (int)(num + 0.5) : (int)(num - 0.5)); } /* Box-Muller, ranges */ double TCOD_random_get_gaussian_double_range (TCOD_random_t mersenne, double min, double max) { double mean, std_deviation, ret; if (min > max) { double tmp = max; max = min; min = tmp; } mean = (min + max) / 2; std_deviation = (max - min) / 6.0; /* 6.0 is used because of the three-sigma rule */ ret = TCOD_random_get_gaussian_double(mersenne, mean, std_deviation); return CLAMP(min,max,ret); } float TCOD_random_get_gaussian_float_range (TCOD_random_t mersenne, float min, float max) { if (min > max) { float tmp = max; max = min; min = tmp; } return (float)TCOD_random_get_gaussian_double_range (mersenne, (double)min, (double)max); } int TCOD_random_get_gaussian_int_range (TCOD_random_t mersenne, int min, int max) { double num; int ret; if (min > max) { int tmp = max; max = min; min = tmp; } num = TCOD_random_get_gaussian_double_range (mersenne, (double)min, (double)max); ret = (num >= 0.0 ? (int)(num + 0.5) : (int)(num - 0.5)); return CLAMP(min,max,ret); } /* Box-Muller, ranges with a custom mean */ double TCOD_random_get_gaussian_double_range_custom (TCOD_random_t mersenne, double min, double max, double mean) { double d1, d2, std_deviation, ret; if (min > max) { double tmp = max; max = min; min = tmp; } d1 = max - mean; d2 = mean - min; std_deviation = MAX(d1,d2) / 3.0; ret = TCOD_random_get_gaussian_double(mersenne, mean, std_deviation); return CLAMP(min,max,ret); } float TCOD_random_get_gaussian_float_range_custom (TCOD_random_t mersenne, float min, float max, float mean) { if (min > max) { float tmp = max; max = min; min = tmp; } return (float)TCOD_random_get_gaussian_double_range_custom (mersenne, (double)min, (double)max, (double)mean); } int TCOD_random_get_gaussian_int_range_custom (TCOD_random_t mersenne, int min, int max, int mean) { double num; int ret; if (min > max) { int tmp = max; max = min; min = tmp; } num = TCOD_random_get_gaussian_double_range_custom (mersenne, (double)min, (double)max, (double)mean); ret = (num >= 0.0 ? (int)(num + 0.5) : (int)(num - 0.5)); return CLAMP(min,max,ret); } /* Box-Muller, inverted distribution */ double TCOD_random_get_gaussian_double_inv (TCOD_random_t mersenne, double mean, double std_deviation) { double num = TCOD_random_get_gaussian_double(mersenne,mean,std_deviation); return (num >= mean ? num - (3 * std_deviation) : num + (3 * std_deviation)); } float TCOD_random_get_gaussian_float_inv (TCOD_random_t mersenne, float mean, float std_deviation) { double num = TCOD_random_get_gaussian_double(mersenne,(double)mean,(double)std_deviation); return (num >= mean ? (float)(num - (3 * std_deviation)) : (float)(num + (3 * std_deviation))); } int TCOD_random_get_gaussian_int_inv (TCOD_random_t mersenne, int mean, int std_deviation) { double num = TCOD_random_get_gaussian_double(mersenne,(double)mean,(double)std_deviation); int inum = (num >= 0.0 ? (int)(num + 0.5) : (int)(num - 0.5)); return (num >= mean ? inum - (3 * std_deviation) : inum + (3 * std_deviation)); } /* Box-Muller, ranges, inverted distribution */ double TCOD_random_get_gaussian_double_range_inv (TCOD_random_t mersenne, double min, double max) { double mean, std_deviation, ret; if (min > max) { double tmp = max; max = min; min = tmp; } mean = (min + max) / 2.0; std_deviation = (max - min) / 6.0; /* 6.0 is used because of the three-sigma rule */ ret = TCOD_random_get_gaussian_double_inv(mersenne, mean, std_deviation); return CLAMP(min,max,ret); } float TCOD_random_get_gaussian_float_range_inv (TCOD_random_t mersenne, float min, float max) { float ret = (float)TCOD_random_get_gaussian_double_range_inv(mersenne, (double)min, (double)max); return CLAMP(min,max,ret); } int TCOD_random_get_gaussian_int_range_inv (TCOD_random_t mersenne, int min, int max) { double num = TCOD_random_get_gaussian_double_range_inv(mersenne, (double)min, (double)max); int ret = (num >= 0.0 ? (int)(num + 0.5) : (int)(num - 0.5)); return CLAMP(min,max,ret); } /* Box-Muller, ranges with a custom mean, inverted distribution */ double TCOD_random_get_gaussian_double_range_custom_inv (TCOD_random_t mersenne, double min, double max, double mean) { double d1, d2, std_deviation, ret; if (min > max) { double tmp = max; max = min; min = tmp; } d1 = max - mean; d2 = mean - min; std_deviation = MAX(d1,d2) / 3.0; ret = TCOD_random_get_gaussian_double_inv(mersenne, mean, std_deviation); return CLAMP(min,max,ret); } float TCOD_random_get_gaussian_float_range_custom_inv (TCOD_random_t mersenne, float min, float max, float mean) { float ret = (float)TCOD_random_get_gaussian_double_range_custom_inv(mersenne, (double)min, (double)max, (double)mean); return CLAMP(min,max,ret); } int TCOD_random_get_gaussian_int_range_custom_inv (TCOD_random_t mersenne, int min, int max, int mean) { double num = TCOD_random_get_gaussian_double_range_custom_inv(mersenne, (double)min, (double)max, (double)mean); int ret = (num >= 0.0 ? (int)(num + 0.5) : (int)(num - 0.5)); return CLAMP(min,max,ret); } void TCOD_random_set_distribution (TCOD_random_t mersenne, TCOD_distribution_t distribution) { mersenne_data_t *r = NULL; if (!mersenne) mersenne=TCOD_random_get_instance(); r = (mersenne_data_t *)mersenne; r->distribution = distribution; } int TCOD_random_get_int (TCOD_random_t mersenne, int min, int max) { if (!mersenne) mersenne=TCOD_random_get_instance(); switch (((mersenne_data_t *)mersenne)->distribution) { case TCOD_DISTRIBUTION_LINEAR: return TCOD_random_get_i(mersenne, min, max); break; case TCOD_DISTRIBUTION_GAUSSIAN: return TCOD_random_get_gaussian_int(mersenne, min, max); break; case TCOD_DISTRIBUTION_GAUSSIAN_INVERSE: return TCOD_random_get_gaussian_int_inv(mersenne, min, max); break; case TCOD_DISTRIBUTION_GAUSSIAN_RANGE: return TCOD_random_get_gaussian_int_range(mersenne, min, max); break; case TCOD_DISTRIBUTION_GAUSSIAN_RANGE_INVERSE: return TCOD_random_get_gaussian_int_range_inv(mersenne, min, max); break; default: return TCOD_random_get_i(mersenne, min, max); break; } } float TCOD_random_get_float (TCOD_random_t mersenne, float min, float max) { if (!mersenne) mersenne=TCOD_random_get_instance(); switch (((mersenne_data_t *)mersenne)->distribution) { case TCOD_DISTRIBUTION_LINEAR: return TCOD_random_get_f(mersenne, min, max); break; case TCOD_DISTRIBUTION_GAUSSIAN: return TCOD_random_get_gaussian_float(mersenne, min, max); break; case TCOD_DISTRIBUTION_GAUSSIAN_INVERSE: return TCOD_random_get_gaussian_float_inv(mersenne, min, max); break; case TCOD_DISTRIBUTION_GAUSSIAN_RANGE: return TCOD_random_get_gaussian_float_range(mersenne, min, max); break; case TCOD_DISTRIBUTION_GAUSSIAN_RANGE_INVERSE: return TCOD_random_get_gaussian_float_range_inv(mersenne, min, max); break; default: return TCOD_random_get_f(mersenne, min, max); break; } } double TCOD_random_get_double (TCOD_random_t mersenne, double min, double max) { if (!mersenne) mersenne=TCOD_random_get_instance(); switch (((mersenne_data_t *)mersenne)->distribution) { case TCOD_DISTRIBUTION_LINEAR: return TCOD_random_get_d(mersenne, min, max); break; case TCOD_DISTRIBUTION_GAUSSIAN: return TCOD_random_get_gaussian_double(mersenne, min, max); break; case TCOD_DISTRIBUTION_GAUSSIAN_INVERSE: return TCOD_random_get_gaussian_double_inv(mersenne, min, max); break; case TCOD_DISTRIBUTION_GAUSSIAN_RANGE: return TCOD_random_get_gaussian_double_range(mersenne, min, max); break; case TCOD_DISTRIBUTION_GAUSSIAN_RANGE_INVERSE: return TCOD_random_get_gaussian_double_range_inv(mersenne, min, max); break; default: return TCOD_random_get_d(mersenne, min, max); break; } } int TCOD_random_get_int_mean (TCOD_random_t mersenne, int min, int max, int mean) { if (!mersenne) mersenne=TCOD_random_get_instance(); switch (((mersenne_data_t *)mersenne)->distribution) { case TCOD_DISTRIBUTION_GAUSSIAN_INVERSE: case TCOD_DISTRIBUTION_GAUSSIAN_RANGE_INVERSE: return TCOD_random_get_gaussian_int_range_custom_inv(mersenne, min, max, mean); break; default: return TCOD_random_get_gaussian_int_range_custom(mersenne, min, max, mean); break; } } float TCOD_random_get_float_mean (TCOD_random_t mersenne, float min, float max, float mean) { if (!mersenne) mersenne=TCOD_random_get_instance(); switch (((mersenne_data_t *)mersenne)->distribution) { case TCOD_DISTRIBUTION_GAUSSIAN_INVERSE: case TCOD_DISTRIBUTION_GAUSSIAN_RANGE_INVERSE: return TCOD_random_get_gaussian_float_range_custom_inv(mersenne, min, max, mean); break; default: return TCOD_random_get_gaussian_float_range_custom(mersenne, min, max, mean); break; } } double TCOD_random_get_double_mean (TCOD_random_t mersenne, double min, double max, double mean) { if (!mersenne) mersenne=TCOD_random_get_instance(); switch (((mersenne_data_t *)mersenne)->distribution) { case TCOD_DISTRIBUTION_GAUSSIAN_INVERSE: case TCOD_DISTRIBUTION_GAUSSIAN_RANGE_INVERSE: return TCOD_random_get_gaussian_double_range_custom_inv(mersenne, min, max, mean); break; default: return TCOD_random_get_gaussian_double_range_custom(mersenne, min, max, mean); break; } } TCOD_dice_t TCOD_random_dice_new (const char * s) { TCOD_dice_t d = { 1, 1, 1.0f, 0.0f }; char * ptr = (char *)s; char tmp[128]; size_t l; /* get multiplier */ if ((l = strcspn(ptr,"*x")) < strlen(ptr)) { strcpy(tmp,ptr); tmp[l] = '\0'; d.multiplier = (float)atof(tmp); ptr += l + 1; } /* get rolls */ l = strcspn(ptr,"dD"); strcpy(tmp,ptr); tmp[l] = '\0'; d.nb_rolls = atoi(tmp); ptr += l + 1; /* get faces */ l = strcspn(ptr,"-+"); strcpy(tmp,ptr); tmp[l] = '\0'; d.nb_faces = atoi(tmp); ptr += l; /* get addsub */ if (strlen(ptr) > 0) { int sign = (*ptr == '+') ? 1 : (-1); ptr++; d.addsub = (float)(atof(ptr) * sign); } return d; } int TCOD_random_dice_roll (TCOD_random_t mersenne, TCOD_dice_t dice) { int rolls; int result = 0; for (rolls = 0; rolls < dice.nb_rolls; rolls++) result += TCOD_random_get_i(mersenne,1,dice.nb_faces); return (int)((result + dice.addsub) * dice.multiplier); } int TCOD_random_dice_roll_s (TCOD_random_t mersenne, const char * s) { return TCOD_random_dice_roll(mersenne,TCOD_random_dice_new(s)); } libtcod-1.6.4+dfsg/src/mouse.cpp000066400000000000000000000035571321276576200165310ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #ifdef TCOD_CONSOLE_SUPPORT void TCODMouse::showCursor(bool visible) { TCOD_mouse_show_cursor(visible); } bool TCODMouse::isCursorVisible() { return TCOD_mouse_is_cursor_visible() != 0; } void TCODMouse::move(int x, int y) { TCOD_mouse_move(x,y); } TCOD_mouse_t TCODMouse::getStatus() { return TCOD_mouse_get_status(); } #endif libtcod-1.6.4+dfsg/src/namegen.cpp000066400000000000000000000042041321276576200170010ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Mingos' NameGen * This file was written by Dominik "Mingos" Marczuk. */ #include void TCODNamegen::parse (const char * filename, TCODRandom * random) { TCOD_namegen_parse (filename, random ? random->data : NULL); } char * TCODNamegen::generate (char * name, bool allocate) { return TCOD_namegen_generate (name, allocate); } char * TCODNamegen::generateCustom (char * name, char * rule, bool allocate) { return TCOD_namegen_generate_custom (name, rule, allocate); } TCOD_list_t TCODNamegen::getSets (void) { return TCOD_namegen_get_sets (); } void TCODNamegen::destroy (void) { TCOD_namegen_destroy (); } libtcod-1.6.4+dfsg/src/namegen_c.c000066400000000000000000000572511321276576200167550ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Mingos' NameGen * This file was written by Dominik "Mingos" Marczuk. */ #include #include #include #include #include #include /* ------------ * * the typedefs * * ------------ */ /* the struct containing a definition of an unprocessed syllable set */ typedef struct { char * name; char * vocals; char * consonants; char * pre; char * start; char * middle; char * end; char * post; char * illegal; char * rules; } namegen_syllables_t; /* and the generator struct */ typedef struct { /* the name that will be called */ char * name; /* needs to use a random number generator */ TCOD_random_t random; /* the lists with all the data */ TCOD_list_t vocals; TCOD_list_t consonants; TCOD_list_t syllables_pre; TCOD_list_t syllables_start; TCOD_list_t syllables_middle; TCOD_list_t syllables_end; TCOD_list_t syllables_post; TCOD_list_t illegal_strings; TCOD_list_t rules; } namegen_t; /* ------------------- * * variables and stuff * * ------------------- */ /* the list containing the generators */ TCOD_list_t namegen_generators_list = NULL; /* the file parser */ TCOD_parser_t namegen_parser; /* parsed files list */ TCOD_list_t parsed_files = NULL; /* the data that will be filled out */ namegen_syllables_t * parser_data = NULL; namegen_t * parser_output = NULL; /* this one's needed to correctly update the generators with RNG pointer */ TCOD_random_t namegen_random; /* the string that will be pointed to upon generating a name */ char * namegen_name = NULL; /* for keeping track of the size of output names */ size_t namegen_name_size; /* ------------------------------------ * * stuff to operate on the syllable set * * ------------------------------------ */ /* initialise a syllable set */ namegen_syllables_t * namegen_syllables_new (void) { namegen_syllables_t * data = calloc(sizeof(namegen_syllables_t),1); return data; } /* free a syllables set */ void namegen_syllables_delete (namegen_syllables_t * data) { if (data->vocals) free(data->vocals); if (data->consonants) free(data->consonants); if (data->pre) free(data->pre); if (data->start) free(data->start); if (data->middle) free(data->middle); if (data->end) free(data->end); if (data->post) free(data->post); if (data->illegal) free(data->illegal); if (data->rules) free(data->rules); free(data->name); free(data); } /* ---------------------------------- * * stuff to operate on the generators * * ---------------------------------- */ /* create a new generator */ namegen_t * namegen_generator_new (void) { namegen_t * data = malloc(sizeof(namegen_t)); data->name = NULL; /* assign the rng */ data->random = TCOD_random_get_instance(); /* create the lists */ data->vocals = TCOD_list_new(); data->consonants = TCOD_list_new(); data->syllables_pre = TCOD_list_new(); data->syllables_start = TCOD_list_new(); data->syllables_middle = TCOD_list_new(); data->syllables_end = TCOD_list_new(); data->syllables_post = TCOD_list_new(); data->illegal_strings = TCOD_list_new(); data->rules = TCOD_list_new(); return (TCOD_namegen_t)data; } /* check whether a given generator already exists */ bool namegen_generator_check (const char * name) { /* if the list is not created yet, create it */ if (namegen_generators_list == NULL) { namegen_generators_list = TCOD_list_new(); return false; } /* otherwise, scan it for the name */ else { namegen_t ** it; for (it = (namegen_t**)TCOD_list_begin(namegen_generators_list); it < (namegen_t**)TCOD_list_end(namegen_generators_list); it++) { if (strcmp((*it)->name,name) == 0) return true; } return false; } } /* retrieve available generator names */ void namegen_get_sets_on_error (void) { namegen_t ** it; fprintf (stderr,"Registered syllable sets are:\n"); for (it = (namegen_t**)TCOD_list_begin(namegen_generators_list); it < (namegen_t**)TCOD_list_end(namegen_generators_list); it++) { fprintf (stderr," * \"%s\"\n",(*it)->name); } } /* get the appropriate syllables set */ namegen_t * namegen_generator_get (const char * name) { if (namegen_generator_check(name) == true) { namegen_t ** it; for (it = (namegen_t**)TCOD_list_begin(namegen_generators_list); it != (namegen_t**)TCOD_list_end(namegen_generators_list); it++) { if (strcmp((*it)->name,name) == 0) return (*it); } } /* and if there's no such set... */ else fprintf(stderr,"Generator \"%s\" could not be retrieved.\n",name); return NULL; } /* destroy a generator */ void namegen_generator_delete (namegen_t * generator) { namegen_t * data = generator; free(data->name); data->random = NULL; TCOD_list_clear_and_delete(data->vocals); TCOD_list_clear_and_delete(data->consonants); TCOD_list_clear_and_delete(data->syllables_pre); TCOD_list_clear_and_delete(data->syllables_start); TCOD_list_clear_and_delete(data->syllables_middle); TCOD_list_clear_and_delete(data->syllables_end); TCOD_list_clear_and_delete(data->syllables_post); TCOD_list_clear_and_delete(data->illegal_strings); TCOD_list_clear_and_delete(data->rules); free(data); } /* ------------------------------ * * Populating namegen_t with data * * ------------------------------ */ /* fill the pointed list with syllable data by extracting tokens */ void namegen_populate_list (char * source, TCOD_list_t list, bool wildcards) { size_t len = strlen(source); size_t i = 0; char * token = malloc(strlen(source)+1); /* tokens will typically be many and very short, but let's be cautious. What if the entire string is a single token?*/ memset(token,'\0',strlen(source)+1); do { /* do the tokenising using an iterator immitation :) */ char * it = source + i; /* append a normal character */ if ((*it >= 'a' && *it <= 'z') || (*it >= 'A' && *it <= 'Z') || *it == '\'' || *it == '-') strncat(token,it,1); /* special character */ else if (*it == '/') { if (wildcards == true) strncat(token,it++,2); else strncat(token,++it,1); i++; } /* underscore is converted to space */ else if (*it == '_') { if (wildcards == true) strncat(token,it,1); else strcat(token," "); } /* add wildcards if they are allowed */ else if (wildcards == true && (*it == '$' || *it == '%' || (*it >= '0' && *it <= '9'))) strncat(token,it,1); /* all other characters are treated as separators and cause adding the current token to the list */ else if (strlen(token) > 0) { TCOD_list_push(list,TCOD_strdup(token)); memset(token,'\0',strlen(source)+1); } } while (++i <= len); free(token); } /* populate all lists of a namegen_t struct */ void namegen_populate (namegen_t * dst, namegen_syllables_t * src) { if (dst == NULL || src == NULL) { fprintf(stderr,"Couldn't populate the name generator with data.\n"); exit(1); } if (src->vocals != NULL) namegen_populate_list (src->vocals,dst->vocals,false); if (src->consonants != NULL) namegen_populate_list (src->consonants,dst->consonants,false); if (src->pre != NULL) namegen_populate_list (src->pre,dst->syllables_pre,false); if (src->start != NULL) namegen_populate_list (src->start,dst->syllables_start,false); if (src->middle != NULL) namegen_populate_list (src->middle,dst->syllables_middle,false); if (src->end != NULL) namegen_populate_list (src->end,dst->syllables_end,false); if (src->post != NULL) namegen_populate_list (src->post,dst->syllables_post,false); if (src->illegal != NULL) namegen_populate_list (src->illegal,dst->illegal_strings,false); if (src->rules != NULL) namegen_populate_list (src->rules,dst->rules,true); dst->name = TCOD_strdup(src->name); } /* -------------------- * * parser-related stuff * * -------------------- */ /* preparing the parser */ void namegen_parser_prepare (void) { static bool namegen_parser_ready = false; if (namegen_parser_ready == true) return; else { TCOD_parser_struct_t parser_name ; namegen_parser = TCOD_parser_new(); parser_name = TCOD_parser_new_struct(namegen_parser, "name"); TCOD_struct_add_property(parser_name, "phonemesVocals", TCOD_TYPE_STRING, false); TCOD_struct_add_property(parser_name, "phonemesConsonants", TCOD_TYPE_STRING, false); TCOD_struct_add_property(parser_name, "syllablesPre", TCOD_TYPE_STRING, false); TCOD_struct_add_property(parser_name, "syllablesStart", TCOD_TYPE_STRING, false); TCOD_struct_add_property(parser_name, "syllablesMiddle", TCOD_TYPE_STRING, false); TCOD_struct_add_property(parser_name, "syllablesEnd", TCOD_TYPE_STRING, false); TCOD_struct_add_property(parser_name, "syllablesPost", TCOD_TYPE_STRING, false); TCOD_struct_add_property(parser_name, "illegal", TCOD_TYPE_STRING, false); TCOD_struct_add_property(parser_name, "rules", TCOD_TYPE_STRING, true); namegen_parser_ready = true; } } /* parser listener */ bool namegen_parser_new_struct (TCOD_parser_struct_t str, const char *name) { parser_data = namegen_syllables_new(); return true; } bool namegen_parser_flag (const char *name) { return true; } bool namegen_parser_property(const char *name, TCOD_value_type_t type, TCOD_value_t value) { if (strcmp(name,"syllablesStart") == 0) parser_data->start = TCOD_strdup(value.s); else if (strcmp(name,"syllablesMiddle") == 0) parser_data->middle = TCOD_strdup(value.s); else if (strcmp(name,"syllablesEnd") == 0) parser_data->end = TCOD_strdup(value.s); else if (strcmp(name,"syllablesPre") == 0) parser_data->pre = TCOD_strdup(value.s); else if (strcmp(name,"syllablesPost") == 0) parser_data->post = TCOD_strdup(value.s); else if (strcmp(name,"phonemesVocals") == 0) parser_data->vocals = TCOD_strdup(value.s); else if (strcmp(name,"phonemesConsonants") == 0) parser_data->consonants = TCOD_strdup(value.s); else if (strcmp(name,"rules") == 0) parser_data->rules = TCOD_strdup(value.s); else if (strcmp(name,"illegal") == 0) { /* illegal strings are converted to lowercase */ char * str ; int i; parser_data->illegal = TCOD_strdup(value.s); str = parser_data->illegal; for(i = 0; i < (int)strlen(str); i++) str[i] = (char)(tolower(str[i])); } else return false; return true; } bool namegen_parser_end_struct(TCOD_parser_struct_t str, const char *name) { /* if there's no syllable set by this name, add it to the list */ if (namegen_generator_check(name) == false) { parser_data->name = TCOD_strdup(name); parser_output = namegen_generator_new(); namegen_populate(parser_output,parser_data); parser_output->random = namegen_random; if (namegen_generators_list == NULL) namegen_generators_list = TCOD_list_new(); TCOD_list_push(namegen_generators_list, (const void*)parser_output); } /* free the allocated memory to prevent a memory leak */ namegen_syllables_delete(parser_data); return true; } void namegen_parser_error(const char *msg) { fprintf(stderr,"%s\n",msg); exit(1); } TCOD_parser_listener_t namegen_listener = { namegen_parser_new_struct, namegen_parser_flag, namegen_parser_property, namegen_parser_end_struct, namegen_parser_error }; /* run the parser */ void namegen_parser_run (const char * filename) { char ** it; /* prepare the parser --- this will be executed only once */ namegen_parser_prepare(); if (parsed_files == NULL) parsed_files = TCOD_list_new(); if (TCOD_list_size(parsed_files) > 0) { for (it = (char **)TCOD_list_begin(parsed_files); it != (char **)TCOD_list_end(parsed_files); it++) if (strcmp(*it,filename) == 0) return; } /* if the file hasn't been parsed yet, add its name to the list so that it's never parsed twice */ TCOD_list_push(parsed_files,(const void *)TCOD_strdup(filename)); /* run the parser */ TCOD_parser_run(namegen_parser,filename,&namegen_listener); } /* --------------- * * rubbish pruning * * --------------- */ /* search for occurrences of triple characters (case-insensitive) */ bool namegen_word_has_triples (char * str) { char * it = str; char c = (char)(tolower(*it)); int cnt = 1; bool has_triples = false; it++; while (*it != '\0') { if ((char)(tolower(*it)) == c) cnt++; else { cnt = 1; c = (char)(tolower(*it)); } if (cnt >= 3) has_triples = true; it++; } return has_triples; } /* search for occurrences of illegal strings */ bool namegen_word_has_illegal (namegen_t * data, char * str) { /* convert word to lowercase */ char * haystack = TCOD_strdup(str); int i; for(i = 0; i < (int)strlen(haystack); i++) haystack[i] = (char)(tolower(haystack[i])); /* look for illegal strings */ if (TCOD_list_size(data->illegal_strings) > 0) { char ** it; for (it = (char**)TCOD_list_begin(data->illegal_strings); it != (char**)TCOD_list_end(data->illegal_strings); it++) { if (strstr(haystack,*it) != NULL) { free(haystack); return true; } } } free(haystack); return false; } /* removes double spaces, as well as leading and ending spaces */ void namegen_word_prune_spaces (char * str) { char * s; char * data = str; /* remove leading spaces */ while (data[0] == ' ') memmove (data, data+1, strlen(data)); /* reduce double spaces to single spaces */ while ((s = strstr(data," ")) != NULL) memmove (s, s+1, strlen(s)); /* remove the final space */ while (data[strlen(data)-1] == ' ') data[strlen(data)-1] = '\0'; } /* prune repeated "syllables", such as Arnarn */ bool namegen_word_prune_syllables (char *str) { char * data = TCOD_strdup(str); size_t len = strlen(data); /* length of the string */ char check[8]; size_t i; /* iteration in for loops */ /* change to lowercase */ for (i = 0; i < len; i++) data[i] = (char)(tolower(data[i])); /* start pruning */ /* 2-character direct repetitions */ for (i = 0; i < len - 4; i++) { memset(check,'\0',8); strncpy(check,data+i,2); strncat(check,data+i,2); if (strstr(data,check) != NULL) { free(data); return true; } } /* 3-character repetitions (anywhere in the word) - prunes everything, even 10-char repetitions */ for (i = 0; i < len - 6; i++) { memset(check,'\0',8); strncpy(check,data+i,3); if (strstr(data+i+3,check) != NULL) { free(data); return true; } } free(data); return false; } /* everything stacked together */ bool namegen_word_is_ok (namegen_t * data, char * str) { namegen_word_prune_spaces(str); return (strlen(str)>0) & (!namegen_word_has_triples(str)) & (!namegen_word_has_illegal(data,str)) & (!namegen_word_prune_syllables(str)); } /* ---------------------------- * * publicly available functions * * ---------------------------- */ /* parse a new syllable sets file - allocates a new data structure and fills it with necessary content */ void TCOD_namegen_parse (const char * filename, TCOD_random_t random) { /* check for file existence */ FILE * in = fopen(filename,"r"); if (in == NULL) { fprintf(stderr,"File \"%s\" not found!\n",filename); return; } fclose(in); /* set namegen RNG */ namegen_random = random; /* run the proper parser - add the file's contents to the data structures */ namegen_parser_run(filename); } /* generate a name using a given generation rule */ char * TCOD_namegen_generate_custom (char * name, char * rule, bool allocate) { namegen_t * data; size_t buflen = 1024; char * buf ; size_t rule_len ; if (namegen_generator_check(name)) data = namegen_generator_get(name); else { fprintf(stderr,"The name \"%s\" has not been found.\n",name); namegen_get_sets_on_error(); return NULL; } buf = malloc(buflen); rule_len = strlen(rule); /* let the show begin! */ do { char * it = rule; memset(buf,'\0',buflen); while (it <= rule + rule_len) { /* make sure the buffer is large enough */ if (strlen(buf) >= buflen) { char * tmp ; while (strlen(buf) >= buflen) buflen *= 2; tmp = malloc(buflen); strcpy(tmp,buf); free(buf); buf = tmp; } /* append a normal character */ if ((*it >= 'a' && *it <= 'z') || (*it >= 'A' && *it <= 'Z') || *it == '\'' || *it == '-') strncat(buf,it,1); /* special character */ else if (*it == '/') { it++; strncat(buf,it,1); } /* underscore is converted to space */ else if (*it == '_') strcat(buf," "); /* interpret a wildcard */ else if (*it == '$') { int chance = 100; it++; /* food for the randomiser */ if (*it >= '0' && *it <= '9') { chance = 0; while (*it >= '0' && *it <= '9') { chance *= 10; chance += (int)(*it) - (int)('0'); it++; } } /* ok, so the chance of wildcard occurrence is calculated, now evaluate it */ if (chance >= TCOD_random_get_int(data->random,0,100)) { TCOD_list_t lst; switch (*it) { case 'P': lst = data->syllables_pre; break; case 's': lst = data->syllables_start; break; case 'm': lst = data->syllables_middle; break; case 'e': lst = data->syllables_end; break; case 'p': lst = data->syllables_post; break; case 'v': lst = data->vocals; break; case 'c': lst = data->consonants; break; case '?': lst = (TCOD_random_get_int(data->random,0,1) == 0 ? data->vocals : data->consonants); break; default: fprintf(stderr,"Wrong rules syntax encountered!\n"); exit(1); break; } if (TCOD_list_size(lst) == 0) fprintf(stderr,"No data found in the requested string (wildcard *%c). Check your name generation rule %s.\n",*it,rule); else strcat(buf,(char*)TCOD_list_get(lst,TCOD_random_get_int(data->random,0,TCOD_list_size(lst)-1))); } } it++; } } while (!namegen_word_is_ok(data,buf)); /* prune the spare spaces out */ namegen_word_prune_spaces(buf); /* return the name accordingly */ if (allocate == true) return buf; else { /* take care of ensuring the recipient is sized properly */ if (namegen_name == NULL) { namegen_name_size = 64; namegen_name = malloc (namegen_name_size); } while (strlen(buf) > namegen_name_size - 1) { namegen_name_size *= 2; free(namegen_name); namegen_name = malloc(namegen_name_size); } strcpy(namegen_name,buf); free(buf); return namegen_name; } } /* generate a name with one of the rules from the file */ char * TCOD_namegen_generate (char * name, bool allocate) { namegen_t * data; int rule_number; int chance; char * rule_rolled; int truncation; char * rule_parsed ; char * ret ; if (namegen_generator_check(name)) data = namegen_generator_get(name); else { fprintf(stderr,"The name \"%s\" has not been found.\n",name); namegen_get_sets_on_error(); return NULL; } /* check if the rules list is present */ if (TCOD_list_size(data->rules) == 0) { fprintf(stderr,"The rules list is empty!\n"); exit(1); } /* choose the rule */ do { rule_number = TCOD_random_get_int(data->random,0,TCOD_list_size(data->rules)-1); rule_rolled = (char*)TCOD_list_get(data->rules,rule_number); chance = 100; truncation = 0; if (rule_rolled[0] == '%') { truncation = 1; chance = 0; while (rule_rolled[truncation] >= '0' && rule_rolled[truncation] <= '9') { chance *= 10; chance += (int)(rule_rolled[truncation]) - (int)('0'); truncation++; } } } while (TCOD_random_get_int(data->random,0,100) > chance); /* OK, we've got ourselves a new rule! */ rule_parsed = TCOD_strdup(rule_rolled+truncation); ret = TCOD_namegen_generate_custom(name,rule_parsed,allocate); free(rule_parsed); return ret; } /* retrieve the list of all available syllable set names */ TCOD_list_t TCOD_namegen_get_sets (void) { TCOD_list_t l = TCOD_list_new(); if (namegen_generators_list != NULL) { namegen_t ** it; for (it = (namegen_t**)TCOD_list_begin(namegen_generators_list); it < (namegen_t**)TCOD_list_end(namegen_generators_list); it++) { TCOD_list_push(l,(const void*)((*it)->name)); } } return l; } /* delete all the generators */ void TCOD_namegen_destroy (void) { /* delete all generators */ namegen_t ** it; for (it = (namegen_t**)TCOD_list_begin(namegen_generators_list); it < (namegen_t**)TCOD_list_end(namegen_generators_list); it++) namegen_generator_delete(*it); /* clear the generators list */ TCOD_list_clear(namegen_generators_list); /* get rid of the parsed files list */ TCOD_list_clear_and_delete(parsed_files); } libtcod-1.6.4+dfsg/src/noise.cpp000066400000000000000000000062351321276576200165120ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include TCODNoise::TCODNoise(int dimensions, TCOD_noise_type_t type) { data = TCOD_noise_new(dimensions, TCOD_NOISE_DEFAULT_HURST, TCOD_NOISE_DEFAULT_LACUNARITY, TCODRandom::getInstance()->data); TCOD_noise_set_type(data,type); } TCODNoise::TCODNoise(int dimensions, TCODRandom *random, TCOD_noise_type_t type) { data = TCOD_noise_new(dimensions, TCOD_NOISE_DEFAULT_HURST, TCOD_NOISE_DEFAULT_LACUNARITY, random->data); TCOD_noise_set_type(data,type); } TCODNoise::TCODNoise(int dimensions, float hurst, float lacunarity, TCOD_noise_type_t type) { data = TCOD_noise_new(dimensions, hurst, lacunarity, TCODRandom::getInstance()->data); TCOD_noise_set_type(data,type); } TCODNoise::TCODNoise(int dimensions, float hurst, float lacunarity, TCODRandom *random, TCOD_noise_type_t type) { data = TCOD_noise_new(dimensions, hurst, lacunarity, random->data); TCOD_noise_set_type(data,type); } void TCODNoise::setType(TCOD_noise_type_t type) { TCOD_noise_set_type(data,type); } float TCODNoise::get (float *f, TCOD_noise_type_t type) { if (type == TCOD_NOISE_DEFAULT) return TCOD_noise_get(data,f); else return TCOD_noise_get_ex(data,f,type); } float TCODNoise::getFbm (float *f, float octaves, TCOD_noise_type_t type) { if (type == TCOD_NOISE_DEFAULT) return TCOD_noise_get_fbm(data,f,octaves); else return TCOD_noise_get_fbm_ex(data,f,octaves,type); } float TCODNoise::getTurbulence (float *f, float octaves, TCOD_noise_type_t type) { if (type == TCOD_NOISE_DEFAULT) return TCOD_noise_get_turbulence(data,f,octaves); else return TCOD_noise_get_turbulence_ex(data,f,octaves,type); } TCODNoise::~TCODNoise() { TCOD_noise_delete(data); } libtcod-1.6.4+dfsg/src/noise_c.c000066400000000000000000000652501321276576200164560ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #define WAVELET_TILE_SIZE 32 #define WAVELET_ARAD 16 #define SIMPLEX_SCALE 0.5f #define WAVELET_SCALE 2.0f typedef struct { int ndim; unsigned char map[256]; /* Randomized map of indexes into buffer */ float buffer[256][TCOD_NOISE_MAX_DIMENSIONS]; /* Random 256 x ndim buffer */ /* fractal stuff */ float H; float lacunarity; float exponent[TCOD_NOISE_MAX_OCTAVES]; float *waveletTileData; TCOD_random_t rand; /* noise type */ TCOD_noise_type_t noise_type; } perlin_data_t; static float lattice( perlin_data_t *data, int ix, float fx, int iy, float fy, int iz, float fz, int iw, float fw) { int n[4] = {ix, iy, iz, iw}; float f[4] = {fx, fy, fz, fw}; int nIndex = 0; int i; float value = 0; for(i=0; indim; i++) nIndex = data->map[(nIndex + n[i]) & 0xFF]; for(i=0; indim; i++) value += data->buffer[nIndex][i] * f[i]; return value; } #define DEFAULT_SEED 0x15687436 #define DELTA 1e-6f #define SWAP(a, b, t) t = a; a = b; b = t #define FLOOR(a) ((a)> 0 ? ((int)a) : (((int)a)-1) ) #define CUBIC(a) ( a * a * (3 - 2*a) ) static void normalize(perlin_data_t *data, float *f) { float magnitude = 0; int i; for(i=0; indim; i++) magnitude += f[i]*f[i]; magnitude = 1.0f / (float)sqrt(magnitude); for(i=0; indim; i++) f[i] *= magnitude; } TCOD_noise_t TCOD_noise_new(int ndim, float hurst, float lacunarity, TCOD_random_t random) { perlin_data_t *data=(perlin_data_t *)calloc(sizeof(perlin_data_t),1); int i, j; unsigned char tmp; float f = 1; data->rand = random ? random : TCOD_random_get_instance(); data->ndim = ndim; for(i=0; i<256; i++) { data->map[i] = (unsigned char)i; for(j=0; jndim; j++) data->buffer[i][j] = TCOD_random_get_float(data->rand,-0.5, 0.5); normalize(data,data->buffer[i]); } while(--i) { j = TCOD_random_get_int(data->rand,0, 255); SWAP(data->map[i], data->map[j], tmp); } data->H = hurst; data->lacunarity = lacunarity; for(i=0; iexponent[i] = 1.0f / f; f *= lacunarity; } data->noise_type = TCOD_NOISE_DEFAULT; return (TCOD_noise_t)data; } float TCOD_noise_perlin( TCOD_noise_t noise, float *f ) { perlin_data_t *data=(perlin_data_t *)noise; int n[TCOD_NOISE_MAX_DIMENSIONS]; /* Indexes to pass to lattice function */ int i; float r[TCOD_NOISE_MAX_DIMENSIONS]; /* Remainders to pass to lattice function */ float w[TCOD_NOISE_MAX_DIMENSIONS]; /* Cubic values to pass to interpolation function */ float value; for(i=0; indim; i++) { n[i] = FLOOR(f[i]); r[i] = f[i] - n[i]; w[i] = CUBIC(r[i]); } switch(data->ndim) { case 1: value = LERP(lattice(data,n[0], r[0],0,0,0,0,0,0), lattice(data,n[0]+1, r[0]-1,0,0,0,0,0,0), w[0]); break; case 2: value = LERP(LERP(lattice(data,n[0], r[0], n[1], r[1],0,0,0,0), lattice(data,n[0]+1, r[0]-1, n[1], r[1],0,0,0,0), w[0]), LERP(lattice(data,n[0], r[0], n[1]+1, r[1]-1,0,0,0,0), lattice(data,n[0]+1, r[0]-1, n[1]+1, r[1]-1,0,0,0,0), w[0]), w[1]); break; case 3: value = LERP(LERP(LERP(lattice(data,n[0], r[0], n[1], r[1], n[2], r[2],0,0), lattice(data,n[0]+1, r[0]-1, n[1], r[1], n[2], r[2],0,0), w[0]), LERP(lattice(data,n[0], r[0], n[1]+1, r[1]-1, n[2], r[2],0,0), lattice(data,n[0]+1, r[0]-1, n[1]+1, r[1]-1, n[2], r[2],0,0), w[0]), w[1]), LERP(LERP(lattice(data,n[0], r[0], n[1], r[1], n[2]+1, r[2]-1,0,0), lattice(data,n[0]+1, r[0]-1, n[1], r[1], n[2]+1, r[2]-1,0,0), w[0]), LERP(lattice(data,n[0], r[0], n[1]+1, r[1]-1, n[2]+1, r[2]-1,0,0), lattice(data,n[0]+1, r[0]-1, n[1]+1, r[1]-1, n[2]+1, r[2]-1,0,0), w[0]), w[1]), w[2]); break; case 4: default: value = LERP(LERP(LERP(LERP(lattice(data,n[0], r[0], n[1], r[1], n[2], r[2], n[3], r[3]), lattice(data,n[0]+1, r[0]-1, n[1], r[1], n[2], r[2], n[3], r[3]), w[0]), LERP(lattice(data,n[0], r[0], n[1]+1, r[1]-1, n[2], r[2], n[3], r[3]), lattice(data,n[0]+1, r[0]-1, n[1]+1, r[1]-1, n[2], r[2], n[3], r[3]), w[0]), w[1]), LERP(LERP(lattice(data,n[0], r[0], n[1], r[1], n[2]+1, r[2]-1, n[3], r[3]), lattice(data,n[0]+1, r[0]-1, n[1], r[1], n[2]+1, r[2]-1, n[3], r[3]), w[0]), LERP(lattice(data,n[0], r[0], n[1]+1, r[1]-1, n[2]+1, r[2]-1,0,0), lattice(data,n[0]+1, r[0]-1, n[1]+1, r[1]-1, n[2]+1, r[2]-1, n[3], r[3]), w[0]), w[1]), w[2]), LERP(LERP(LERP(lattice(data,n[0], r[0], n[1], r[1], n[2], r[2], n[3]+1, r[3]-1), lattice(data,n[0]+1, r[0]-1, n[1], r[1], n[2], r[2], n[3]+1, r[3]-1), w[0]), LERP(lattice(data,n[0], r[0], n[1]+1, r[1]-1, n[2], r[2], n[3]+1, r[3]-1), lattice(data,n[0]+1, r[0]-1, n[1]+1, r[1]-1, n[2], r[2], n[3]+1, r[3]-1), w[0]), w[1]), LERP(LERP(lattice(data,n[0], r[0], n[1], r[1], n[2]+1, r[2]-1, n[3]+1, r[3]-1), lattice(data,n[0]+1, r[0]-1, n[1], r[1], n[2]+1, r[2]-1, n[3]+1, r[3]-1), w[0]), LERP(lattice(data,n[0], r[0], n[1]+1, r[1]-1, n[2]+1, r[2]-1,0,0), lattice(data,n[0]+1, r[0]-1, n[1]+1, r[1]-1, n[2]+1, r[2]-1, n[3]+1, r[3]-1), w[0]), w[1]), w[2]), w[3]); break; } return CLAMP(-0.99999f, 0.99999f, value); } static int absmod(int x, int n) { int m=x%n; return m < 0 ? m+n : m; } /* simplex noise, adapted from Ken Perlin's presentation at Siggraph 2001 */ /* and Stefan Gustavson implementation */ #define TCOD_NOISE_SIMPLEX_GRADIENT_1D(n,h,x) { float grad; h &= 0xF; grad=1.0f+(h & 7); if ( h & 8 ) grad = -grad; n = grad * x; } #define TCOD_NOISE_SIMPLEX_GRADIENT_2D(n,h,x,y) { float u,v; h &= 0x7; if ( h < 4 ) { u=x; v=2.0f*y; } else { u=y; v=2.0f*x; } n = ((h & 1) ? -u : u) + ((h & 2) ? -v :v ); } #define TCOD_NOISE_SIMPLEX_GRADIENT_3D(n,h,x,y,z) { float u,v; h &= 0xF; u = (h < 8 ? x : y); v = (h < 4 ? y : ( h == 12 || h == 14 ? x : z ) ); n= ((h & 1) ? -u : u ) + ((h & 2) ? -v : v); } #define TCOD_NOISE_SIMPLEX_GRADIENT_4D(n,h,x,y,z,t) { float u,v,w; h &= 0x1F; u = (h < 24 ? x:y); v = (h < 16 ? y:z); w = (h < 8 ? z:t); n= ((h & 1) ? -u : u ) + ((h & 2) ? -v : v) + ((h & 4) ? -w : w);} static float simplex[64][4] = { {0,1,2,3},{0,1,3,2},{0,0,0,0},{0,2,3,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,2,3,0}, {0,2,1,3},{0,0,0,0},{0,3,1,2},{0,3,2,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,3,2,0}, {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, {1,2,0,3},{0,0,0,0},{1,3,0,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,3,0,1},{2,3,1,0}, {1,0,2,3},{1,0,3,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,0,3,1},{0,0,0,0},{2,1,3,0}, {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, {2,0,1,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,0,1,2},{3,0,2,1},{0,0,0,0},{3,1,2,0}, {2,1,0,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,1,0,2},{0,0,0,0},{3,2,0,1},{3,2,1,0}, }; float TCOD_noise_simplex(TCOD_noise_t noise, float *f) { perlin_data_t *data=(perlin_data_t *)noise; switch(data->ndim) { case 1 : { int i0=(int)FLOOR(f[0]*SIMPLEX_SCALE); int i1=i0+1; float x0 = f[0]*SIMPLEX_SCALE - i0; float x1 = x0 - 1.0f; float t0 = 1.0f - x0*x0; float t1 = 1.0f - x1*x1; float n0,n1; t0 = t0*t0; t1 = t1*t1; i0=data->map[i0&0xFF]; TCOD_NOISE_SIMPLEX_GRADIENT_1D(n0,i0,x0); n0*=t0*t0; i1=data->map[i1&0xFF]; TCOD_NOISE_SIMPLEX_GRADIENT_1D(n1,i1,x1); n1*=t1*t1; return 0.25f * (n0+n1); } break; case 2 : { #define F2 0.366025403f /* 0.5f * (sqrtf(3.0f)-1.0f); */ #define G2 0.211324865f /* (3.0f - sqrtf(3.0f))/6.0f; */ float s = (f[0]+f[1])*F2*SIMPLEX_SCALE; float xs = f[0]*SIMPLEX_SCALE+s; float ys = f[1]*SIMPLEX_SCALE+s; int i=FLOOR(xs); int j=FLOOR(ys); float t = (i+j)*G2; float xo = i-t; float yo = j-t; float x0 = f[0]*SIMPLEX_SCALE-xo; float y0 = f[1]*SIMPLEX_SCALE-yo; int i1,j1,ii = absmod(i ,256),jj = absmod(j, 256); float n0,n1,n2,x1,y1,x2,y2,t0,t1,t2; if ( x0 > y0 ) { i1=1;j1=0; } else { i1=0;j1=1; } x1 = x0 - i1 + G2; y1 = y0 - j1 + G2; x2 = x0 - 1.0f + 2.0f * G2; y2 = y0 - 1.0f + 2.0f * G2; t0 = 0.5f - x0*x0 - y0*y0; if ( t0 < 0.0f ) { n0 = 0.0f; } else { int idx = (ii + data->map[jj])&0xFF; t0 *= t0; idx=data->map[idx]; TCOD_NOISE_SIMPLEX_GRADIENT_2D(n0,idx,x0,y0); n0 *= t0*t0; } t1 = 0.5f - x1*x1 -y1*y1; if ( t1 < 0.0f ) { n1 = 0.0f; } else { int idx = (ii + i1 + data->map[(jj+j1)&0xFF]) & 0xFF; t1 *= t1; idx=data->map[idx]; TCOD_NOISE_SIMPLEX_GRADIENT_2D(n1,idx,x1,y1); n1 *= t1*t1; } t2 = 0.5f - x2*x2 -y2*y2; if ( t2 < 0.0f ) { n2 = 0.0f; } else { int idx = (ii + 1 + data->map[(jj+1)&0xFF]) & 0xFF; t2 *= t2; idx=data->map[idx]; TCOD_NOISE_SIMPLEX_GRADIENT_2D(n2,idx,x2,y2); n2 *= t2*t2; } return 40.0f * (n0+n1+n2); } break; case 3 : { #define F3 0.333333333f #define G3 0.166666667f float n0,n1,n2,n3; float s =(f[0]+f[1]+f[2])*F3*SIMPLEX_SCALE; float xs=f[0]*SIMPLEX_SCALE+s; float ys=f[1]*SIMPLEX_SCALE+s; float zs=f[2]*SIMPLEX_SCALE+s; int i=FLOOR(xs); int j=FLOOR(ys); int k=FLOOR(zs); float t=(float)(i+j+k)*G3; float xo = i-t; float yo = j-t; float zo = k-t; float x0 = f[0]*SIMPLEX_SCALE-xo; float y0 = f[1]*SIMPLEX_SCALE-yo; float z0 = f[2]*SIMPLEX_SCALE-zo; int i1,j1,k1,i2,j2,k2,ii,jj,kk; float x1,y1,z1,x2,y2,z2,x3,y3,z3,t0,t1,t2,t3; if ( x0 >= y0 ) { if ( y0 >= z0 ) { i1=1;j1=0;k1=0;i2=1;j2=1;k2=0; } else if ( x0 >= z0 ) { i1=1;j1=0;k1=0;i2=1;j2=0;k2=1; } else { i1=0;j1=0;k1=1;i2=1;j2=0;k2=1; } } else { if ( y0 < z0 ) { i1=0;j1=0;k1=1;i2=0;j2=1;k2=1; } else if ( x0 < z0 ) { i1=0;j1=1;k1=0;i2=0;j2=1;k2=1; } else { i1=0;j1=1;k1=0;i2=1;j2=1;k2=0; } } x1 = x0 -i1 + G3; y1 = y0 -j1 + G3; z1 = z0 -k1 + G3; x2 = x0 -i2 + 2.0f*G3; y2 = y0 -j2 + 2.0f*G3; z2 = z0 -k2 + 2.0f*G3; x3 = x0 - 1.0f +3.0f * G3; y3 = y0 - 1.0f +3.0f * G3; z3 = z0 - 1.0f +3.0f * G3; ii = absmod(i, 256); jj = absmod(j, 256); kk = absmod(k, 256); t0 = 0.6f - x0*x0 -y0*y0 -z0*z0; if ( t0 < 0.0f ) n0 = 0.0f; else { int idx = data->map[ (ii + data->map[ (jj + data->map[ kk ]) &0xFF ])& 0xFF ]; t0 *= t0; TCOD_NOISE_SIMPLEX_GRADIENT_3D(n0,idx,x0,y0,z0); n0 *= t0*t0; } t1 = 0.6f - x1*x1 -y1*y1 -z1*z1; if ( t1 < 0.0f ) n1 = 0.0f; else { int idx = data->map[ (ii + i1 + data->map[ (jj + j1 + data->map[ (kk + k1)& 0xFF ]) &0xFF ])& 0xFF ]; t1 *= t1; TCOD_NOISE_SIMPLEX_GRADIENT_3D(n1,idx,x1,y1,z1); n1 *= t1*t1; } t2 = 0.6f - x2*x2 -y2*y2 -z2*z2; if ( t2 < 0.0f ) n2 = 0.0f; else { int idx = data->map[ (ii + i2 + data->map[ (jj + j2 + data->map[ (kk + k2)& 0xFF ]) &0xFF ])& 0xFF ]; t2 *= t2; TCOD_NOISE_SIMPLEX_GRADIENT_3D(n2,idx,x2,y2,z2); n2 *= t2*t2; } t3 = 0.6f - x3*x3 -y3*y3 -z3*z3; if ( t3 < 0.0f ) n3 = 0.0f; else { int idx = data->map[ (ii + 1 + data->map[ (jj + 1 + data->map[ (kk + 1)& 0xFF ]) &0xFF ])& 0xFF ]; t3 *= t3; TCOD_NOISE_SIMPLEX_GRADIENT_3D(n3,idx,x3,y3,z3); n3 *= t3*t3; } return 32.0f * (n0+n1+n2+n3); } break; case 4 : { #define F4 0.309016994f /* (sqrtf(5.0f)-1.0f)/4.0f */ #define G4 0.138196601f /* (5.0f - sqrtf(5.0f))/20.0f */ float n0,n1,n2,n3,n4; float s = (f[0]+f[1]+f[2]+f[3])*F4 * SIMPLEX_SCALE; float xs=f[0]*SIMPLEX_SCALE+s; float ys=f[1]*SIMPLEX_SCALE+s; float zs=f[2]*SIMPLEX_SCALE+s; float ws=f[3]*SIMPLEX_SCALE+s; int i=FLOOR(xs); int j=FLOOR(ys); int k=FLOOR(zs); int l=FLOOR(ws); float t=(float)(i+j+k+l)*G4; float xo = i-t; float yo = j-t; float zo = k-t; float wo = l-t; float x0 = f[0]*SIMPLEX_SCALE-xo; float y0 = f[1]*SIMPLEX_SCALE-yo; float z0 = f[2]*SIMPLEX_SCALE-zo; float w0 = f[3]*SIMPLEX_SCALE-wo; int c1 = (x0 > y0 ? 32 : 0); int c2 = (x0 > z0 ? 16 : 0); int c3 = (y0 > z0 ? 8 : 0); int c4 = (x0 > w0 ? 4 : 0); int c5 = (y0 > w0 ? 2 : 0); int c6 = (z0 > w0 ? 1 : 0); int c = c1+c2+c3+c4+c5+c6; int i1,j1,k1,l1,i2,j2,k2,l2,i3,j3,k3,l3,ii,jj,kk,ll; float x1,y1,z1,w1,x2,y2,z2,w2,x3,y3,z3,w3,x4,y4,z4,w4,t0,t1,t2,t3,t4; i1 = simplex[c][0] >= 3 ? 1:0; j1 = simplex[c][1] >= 3 ? 1:0; k1 = simplex[c][2] >= 3 ? 1:0; l1 = simplex[c][3] >= 3 ? 1:0; i2 = simplex[c][0] >= 2 ? 1:0; j2 = simplex[c][1] >= 2 ? 1:0; k2 = simplex[c][2] >= 2 ? 1:0; l2 = simplex[c][3] >= 2 ? 1:0; i3 = simplex[c][0] >= 1 ? 1:0; j3 = simplex[c][1] >= 1 ? 1:0; k3 = simplex[c][2] >= 1 ? 1:0; l3 = simplex[c][3] >= 1 ? 1:0; x1 = x0 -i1 + G4; y1 = y0 -j1 + G4; z1 = z0 -k1 + G4; w1 = w0 -l1 + G4; x2 = x0 -i2 + 2.0f*G4; y2 = y0 -j2 + 2.0f*G4; z2 = z0 -k2 + 2.0f*G4; w2 = w0 -l2 + 2.0f*G4; x3 = x0 -i3 + 3.0f*G4; y3 = y0 -j3 + 3.0f*G4; z3 = z0 -k3 + 3.0f*G4; w3 = w0 -l3 + 3.0f*G4; x4 = x0 - 1.0f +4.0f * G4; y4 = y0 - 1.0f +4.0f * G4; z4 = z0 - 1.0f +4.0f * G4; w4 = w0 - 1.0f +4.0f * G4; ii = absmod(i, 256); jj = absmod(j, 256); kk = absmod(k, 256); ll = absmod(l, 256); t0 = 0.6f - x0*x0 -y0*y0 -z0*z0 -w0*w0; if ( t0 < 0.0f ) n0 = 0.0f; else { int idx = data->map[ (ii + data->map[ (jj + data->map[ (kk + data->map[ ll ] ) &0xFF]) &0xFF ])& 0xFF ]; t0 *= t0; TCOD_NOISE_SIMPLEX_GRADIENT_4D(n0,idx,x0,y0,z0,w0); n0 *= t0*t0; } t1 = 0.6f - x1*x1 -y1*y1 -z1*z1 -w1*w1; if ( t1 < 0.0f ) n1 = 0.0f; else { int idx = data->map[ (ii + i1 + data->map[ (jj + j1 + data->map[ (kk + k1 + data->map[ (ll+l1)&0xFF])& 0xFF ]) &0xFF ])& 0xFF ]; t1 *= t1; TCOD_NOISE_SIMPLEX_GRADIENT_4D(n1,idx,x1,y1,z1,w1); n1 *= t1*t1; } t2 = 0.6f - x2*x2 -y2*y2 -z2*z2 -w2*w2; if ( t2 < 0.0f ) n2 = 0.0f; else { int idx = data->map[ (ii + i2 + data->map[ (jj + j2 + data->map[ (kk + k2 + data->map[(ll+l2)&0xFF])& 0xFF ]) &0xFF ])& 0xFF ]; t2 *= t2; TCOD_NOISE_SIMPLEX_GRADIENT_4D(n2,idx,x2,y2,z2,w2); n2 *= t2*t2; } t3 = 0.6f - x3*x3 -y3*y3 -z3*z3 -w3*w3; if ( t3 < 0.0f ) n3 = 0.0f; else { int idx = data->map[ (ii + i3 + data->map[ (jj + j3 + data->map[ (kk + k3 + data->map[(ll+l3)&0xFF])& 0xFF ]) &0xFF ])& 0xFF ]; t3 *= t3; TCOD_NOISE_SIMPLEX_GRADIENT_4D(n3,idx,x3,y3,z3,w3); n3 *= t3*t3; } t4 = 0.6f - x4*x4 -y4*y4 -z4*z4 -w4*w4; if ( t4 < 0.0f ) n4 = 0.0f; else { int idx = data->map[ (ii + 1 + data->map[ (jj + 1 + data->map[ (kk + 1 + data->map[(ll+1)&0xFF])& 0xFF ]) &0xFF ])& 0xFF ]; t4 *= t4; TCOD_NOISE_SIMPLEX_GRADIENT_4D(n4,idx,x4,y4,z4,w4); n4 *= t4*t4; } return 27.0f * (n0+n1+n2+n3+n4); } break; } return 0.0f; } typedef float (*TCOD_noise_func_t)( TCOD_noise_t noise, float *f ); static float TCOD_noise_fbm_int(TCOD_noise_t noise, float *f, float octaves, TCOD_noise_func_t func ) { float tf[TCOD_NOISE_MAX_DIMENSIONS]; perlin_data_t *data=(perlin_data_t *)noise; /* Initialize locals */ double value = 0; int i,j; memcpy(tf,f,sizeof(float)*data->ndim); /* Inner loop of spectral construction, where the fractal is built */ for(i=0; i<(int)octaves; i++) { value += (double)(func(noise,tf)) * data->exponent[i]; for (j=0; j < data->ndim; j++) tf[j] *= data->lacunarity; } /* Take care of remainder in octaves */ octaves -= (int)octaves; if(octaves > DELTA) value += (double)(octaves * func(noise,tf)) * data->exponent[i]; return CLAMP(-0.99999f, 0.99999f, (float)value); } float TCOD_noise_fbm_perlin( TCOD_noise_t noise, float *f, float octaves ) { return TCOD_noise_fbm_int(noise,f,octaves,TCOD_noise_perlin); } float TCOD_noise_fbm_simplex( TCOD_noise_t noise, float *f, float octaves ) { return TCOD_noise_fbm_int(noise,f,octaves,TCOD_noise_simplex); } static float TCOD_noise_turbulence_int( TCOD_noise_t noise, float *f, float octaves, TCOD_noise_func_t func ) { float tf[TCOD_NOISE_MAX_DIMENSIONS]; perlin_data_t *data=(perlin_data_t *)noise; /* Initialize locals */ double value = 0; int i,j; memcpy(tf,f,sizeof(float)*data->ndim); /* Inner loop of spectral construction, where the fractal is built */ for(i=0; i<(int)octaves; i++) { float nval=func(noise,tf); value += (double)(ABS(nval)) * data->exponent[i]; for (j=0; j < data->ndim; j++) tf[j] *= data->lacunarity; } /* Take care of remainder in octaves */ octaves -= (int)octaves; if(octaves > DELTA) { float nval=func(noise,tf); value += (double)(octaves * ABS(nval)) * data->exponent[i]; } return CLAMP(-0.99999f, 0.99999f, (float)value); } float TCOD_noise_turbulence_perlin( TCOD_noise_t noise, float *f, float octaves ) { return TCOD_noise_turbulence_int(noise,f,octaves,TCOD_noise_perlin); } float TCOD_noise_turbulence_simplex( TCOD_noise_t noise, float *f, float octaves ) { return TCOD_noise_turbulence_int(noise,f,octaves,TCOD_noise_simplex); } /* wavelet noise, adapted from Robert L. Cook and Tony Derose 'Wavelet noise' paper */ static void TCOD_noise_wavelet_downsample(float *from, float *to, int stride) { static float acoeffs[2*WAVELET_ARAD]= { 0.000334f, -0.001528f, 0.000410f, 0.003545f, -0.000938f, -0.008233f, 0.002172f, 0.019120f, -0.005040f,-0.044412f, 0.011655f, 0.103311f, -0.025936f, -0.243780f, 0.033979f, 0.655340f, 0.655340f, 0.033979f,-0.243780f,-0.025936f, 0.103311f, 0.011655f,-0.044412f,-0.005040f, 0.019120f, 0.002172f,-0.008233f,-0.000938f, 0.003546f, 0.000410f,-0.001528f, 0.000334f, }; static float *a = &acoeffs[WAVELET_ARAD]; int i; for (i=0; i < WAVELET_TILE_SIZE/2; i++) { int k; to[i*stride]=0; for (k=2*i-WAVELET_ARAD; k <2*i+WAVELET_ARAD; k++) { to[i*stride] += a[k-2*i]* from[ absmod(k,WAVELET_TILE_SIZE) * stride ]; } } } static void TCOD_noise_wavelet_upsample(float *from, float *to, int stride) { static float pcoeffs[4]= { 0.25f, 0.75f, 0.75f, 0.25f }; static float *p = &pcoeffs[2]; int i; for (i=0; i < WAVELET_TILE_SIZE; i++) { int k; to[i*stride]=0; for (k=i/2; k rand,-1.0f,1.0f); } for (iy=0; iy < WAVELET_TILE_SIZE; iy++ ) { for (iz=0; iz < WAVELET_TILE_SIZE; iz++ ) { i = iy * WAVELET_TILE_SIZE + iz * WAVELET_TILE_SIZE * WAVELET_TILE_SIZE; TCOD_noise_wavelet_downsample(&noise[i], &temp1[i], 1); TCOD_noise_wavelet_upsample(&temp1[i], &temp2[i], 1); } } for (ix=0; ix < WAVELET_TILE_SIZE; ix++ ) { for (iz=0; iz < WAVELET_TILE_SIZE; iz++ ) { i = ix + iz * WAVELET_TILE_SIZE * WAVELET_TILE_SIZE; TCOD_noise_wavelet_downsample(&temp2[i], &temp1[i], WAVELET_TILE_SIZE); TCOD_noise_wavelet_upsample(&temp1[i], &temp2[i], WAVELET_TILE_SIZE); } } for (ix=0; ix < WAVELET_TILE_SIZE; ix++ ) { for (iy=0; iy < WAVELET_TILE_SIZE; iy++ ) { i = ix + iy * WAVELET_TILE_SIZE; TCOD_noise_wavelet_downsample(&temp2[i], &temp1[i], WAVELET_TILE_SIZE * WAVELET_TILE_SIZE); TCOD_noise_wavelet_upsample(&temp1[i], &temp2[i], WAVELET_TILE_SIZE * WAVELET_TILE_SIZE); } } for (i=0; i < WAVELET_TILE_SIZE*WAVELET_TILE_SIZE*WAVELET_TILE_SIZE; i++ ) { noise[i] -= temp2[i]; } offset = WAVELET_TILE_SIZE/2; if ( (offset & 1) == 0 ) offset++; for (i=0,ix=0; ix < WAVELET_TILE_SIZE; ix++ ) { for (iy=0; iy < WAVELET_TILE_SIZE; iy++ ) { for (iz=0; iz < WAVELET_TILE_SIZE; iz++ ) { temp1[i++]=noise[ absmod(ix+offset,WAVELET_TILE_SIZE) + absmod(iy+offset,WAVELET_TILE_SIZE)*WAVELET_TILE_SIZE + absmod(iz+offset,WAVELET_TILE_SIZE)*WAVELET_TILE_SIZE*WAVELET_TILE_SIZE ]; } } } for (i=0; i < WAVELET_TILE_SIZE*WAVELET_TILE_SIZE*WAVELET_TILE_SIZE; i++ ) { noise[i] += temp1[i]; } data->waveletTileData=noise; free(temp1); free(temp2); } float TCOD_noise_wavelet (TCOD_noise_t noise, float *f) { perlin_data_t *data=(perlin_data_t *)noise; float pf[3]; int i; int p[3],c[3],mid[3],n=WAVELET_TILE_SIZE; float w[3][3],t,result=0.0f; if ( data->ndim > 3 ) return 0.0f; /* not supported */ if (! data->waveletTileData ) TCOD_noise_wavelet_init(noise); for (i=0; i < data->ndim; i++ ) pf[i]=f[i]*WAVELET_SCALE; for (i=data->ndim; i < 3; i++ ) pf[i]=0.0f; for (i=0; i < 3; i++ ) { mid[i]=(int)ceil(pf[i]-0.5f); t=mid[i] - (pf[i]-0.5f); w[i][0]=t*t*0.5f; w[i][2]=(1.0f-t)*(1.0f-t)*0.5f; w[i][1]=1.0f - w[i][0]-w[i][2]; } for (p[2]=-1; p[2]<=1; p[2]++) { for (p[1]=-1; p[1]<=1; p[1]++) { for (p[0]=-1; p[0]<=1; p[0]++) { float weight=1.0f; for (i=0;i<3;i++) { c[i]=absmod(mid[i]+p[i],n); weight *= w[i][p[i]+1]; } result += weight * data->waveletTileData[ c[2]*n*n + c[1]*n + c[0] ]; } } } return CLAMP(-1.0f,1.0f,result); } float TCOD_noise_fbm_wavelet(TCOD_noise_t noise, float *f, float octaves) { return TCOD_noise_fbm_int(noise,f,octaves,TCOD_noise_wavelet); } float TCOD_noise_turbulence_wavelet(TCOD_noise_t noise, float *f, float octaves) { return TCOD_noise_turbulence_int(noise,f,octaves,TCOD_noise_wavelet); } void TCOD_noise_set_type (TCOD_noise_t noise, TCOD_noise_type_t type) { ((perlin_data_t *)noise)->noise_type = type; } float TCOD_noise_get_ex (TCOD_noise_t noise, float *f, TCOD_noise_type_t type) { switch (type) { case (TCOD_NOISE_PERLIN): return TCOD_noise_perlin(noise,f); break; case (TCOD_NOISE_SIMPLEX): return TCOD_noise_simplex(noise,f); break; case (TCOD_NOISE_WAVELET): return TCOD_noise_wavelet(noise,f); break; default: switch (((perlin_data_t *)noise)->noise_type) { case (TCOD_NOISE_PERLIN): return TCOD_noise_perlin(noise,f); break; case (TCOD_NOISE_SIMPLEX): return TCOD_noise_simplex(noise,f); break; case (TCOD_NOISE_WAVELET): return TCOD_noise_wavelet(noise,f); break; default: return TCOD_noise_simplex(noise,f); break; } break; } } float TCOD_noise_get_fbm_ex (TCOD_noise_t noise, float *f, float octaves, TCOD_noise_type_t type) { switch (type) { case (TCOD_NOISE_PERLIN): return TCOD_noise_fbm_perlin(noise,f,octaves); break; case (TCOD_NOISE_SIMPLEX): return TCOD_noise_fbm_simplex(noise,f,octaves); break; case (TCOD_NOISE_WAVELET): return TCOD_noise_fbm_wavelet(noise,f,octaves); break; default: switch (((perlin_data_t *)noise)->noise_type) { case (TCOD_NOISE_PERLIN): return TCOD_noise_fbm_perlin(noise,f,octaves); break; case (TCOD_NOISE_SIMPLEX): return TCOD_noise_fbm_simplex(noise,f,octaves); break; case (TCOD_NOISE_WAVELET): return TCOD_noise_fbm_wavelet(noise,f,octaves); break; default: return TCOD_noise_fbm_simplex(noise,f,octaves); break; } break; } } float TCOD_noise_get_turbulence_ex (TCOD_noise_t noise, float *f, float octaves, TCOD_noise_type_t type) { switch (type) { case (TCOD_NOISE_PERLIN): return TCOD_noise_turbulence_perlin(noise,f,octaves); break; case (TCOD_NOISE_SIMPLEX): return TCOD_noise_turbulence_simplex(noise,f,octaves); break; case (TCOD_NOISE_WAVELET): return TCOD_noise_turbulence_wavelet(noise,f,octaves); break; default: switch (((perlin_data_t *)noise)->noise_type) { case (TCOD_NOISE_PERLIN): return TCOD_noise_turbulence_perlin(noise,f,octaves); break; case (TCOD_NOISE_SIMPLEX): return TCOD_noise_turbulence_simplex(noise,f,octaves); break; case (TCOD_NOISE_WAVELET): return TCOD_noise_turbulence_wavelet(noise,f,octaves); break; default: return TCOD_noise_turbulence_simplex(noise,f,octaves); break; } break; } } float TCOD_noise_get (TCOD_noise_t noise, float *f) { switch (((perlin_data_t *)noise)->noise_type) { case (TCOD_NOISE_PERLIN): return TCOD_noise_perlin(noise,f); break; case (TCOD_NOISE_SIMPLEX): return TCOD_noise_simplex(noise,f); break; case (TCOD_NOISE_WAVELET): return TCOD_noise_wavelet(noise,f); break; default: return TCOD_noise_simplex(noise,f); break; } } float TCOD_noise_get_fbm (TCOD_noise_t noise, float *f, float octaves) { switch (((perlin_data_t *)noise)->noise_type) { case (TCOD_NOISE_PERLIN): return TCOD_noise_fbm_perlin(noise,f,octaves); break; case (TCOD_NOISE_SIMPLEX): return TCOD_noise_fbm_simplex(noise,f,octaves); break; case (TCOD_NOISE_WAVELET): return TCOD_noise_fbm_wavelet(noise,f,octaves); break; default: return TCOD_noise_fbm_simplex(noise,f,octaves); break; } } float TCOD_noise_get_turbulence (TCOD_noise_t noise, float *f, float octaves) { switch (((perlin_data_t *)noise)->noise_type) { case (TCOD_NOISE_PERLIN): return TCOD_noise_turbulence_perlin(noise,f,octaves); break; case (TCOD_NOISE_SIMPLEX): return TCOD_noise_turbulence_simplex(noise,f,octaves); break; case (TCOD_NOISE_WAVELET): return TCOD_noise_turbulence_wavelet(noise,f,octaves); break; default: return TCOD_noise_turbulence_simplex(noise,f,octaves); break; } } void TCOD_noise_delete(TCOD_noise_t noise) { if (((perlin_data_t *)noise)->waveletTileData) { free(((perlin_data_t *)noise)->waveletTileData); } free((perlin_data_t *)noise); } libtcod-1.6.4+dfsg/src/parser.cpp000066400000000000000000000140761321276576200166730ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include const char *TCODParserStruct::getName() const { return TCOD_struct_get_name(data); } TCODParserStruct* TCODParserStruct::addProperty(const char *propname, TCOD_value_type_t type, bool mandatory) { TCOD_struct_add_property(data,propname,type,mandatory); return this; } TCODParserStruct* TCODParserStruct::addListProperty(const char *propname, TCOD_value_type_t type, bool mandatory) { TCOD_struct_add_list_property(data,propname,type,mandatory); return this; } TCODParserStruct* TCODParserStruct::addValueList(const char *propname, const char **value_list, bool mandatory) { TCOD_struct_add_value_list(data,propname,value_list,mandatory); return this; } TCODParserStruct* TCODParserStruct::addFlag(const char *propname) { TCOD_struct_add_flag(data,propname); return this; } TCODParserStruct* TCODParserStruct::addStructure(TCODParserStruct *sub_entity) { TCOD_struct_add_structure(data,sub_entity->data); return this; } bool TCODParserStruct::isPropertyMandatory(const char *propname) const { return TCOD_struct_is_mandatory(data,propname) != 0; } TCOD_value_type_t TCODParserStruct::getPropertyType(const char *propname) const { return TCOD_struct_get_type(data,propname); } TCODParserStruct *TCODParser::newStructure(const char *name) { TCODParserStruct *ent = new TCODParserStruct(); ent->data = TCOD_parser_new_struct(data,(char *)name); defs.push(ent); return ent; } static ITCODParserListener *listener=NULL; static TCODParser *parser=NULL; extern "C" bool new_struct(TCOD_parser_struct_t def,const char *name) { for ( TCODParserStruct **idef=parser->defs.begin(); idef != parser->defs.end(); idef++) { if ( (*idef)->data == def ) { return listener->parserNewStruct(parser,*idef,name) ? 1 : 0; } } // not found. autodeclaring struct TCODParserStruct *idef = new TCODParserStruct(); idef->data = def; parser->defs.push(idef); return listener->parserNewStruct(parser,idef,name) ? 1 : 0; } extern "C" bool new_flag(const char *name) { return listener->parserFlag(parser,name) ? 1 : 0; } extern "C" bool new_property(const char *propname, TCOD_value_type_t type, TCOD_value_t value) { return listener->parserProperty(parser,propname,type, value) ? 1 : 0; } extern "C" bool end_struct(TCOD_parser_struct_t def, const char *name) { for ( TCODParserStruct **idef=parser->defs.begin(); idef != parser->defs.end(); idef++) { if ( (*idef)->data == def ) { return listener->parserEndStruct(parser,*idef,name) ? 1 : 0; } } return 0; } extern "C" void error(const char *msg) { listener->error(msg); } static TCOD_parser_listener_t c_to_cpp_listener = { new_struct, new_flag, new_property, end_struct, error }; TCODParser::TCODParser() { data = TCOD_parser_new(); } TCODParser::~TCODParser() { TCOD_parser_delete(data); } void TCODParser::run(const char *filename, ITCODParserListener *_listener) { listener=_listener; parser=this; if ( listener ) TCOD_parser_run(data,(char *)filename,&c_to_cpp_listener); else TCOD_parser_run(data,(char *)filename, NULL); } TCOD_value_type_t TCODParser::newCustomType(TCOD_parser_custom_t custom_type_parser) { return TCOD_parser_new_custom_type(data,custom_type_parser); } void TCODParser::error(const char *msg, ...) { char buf[2048]; va_list ap; va_start(ap,msg); vsprintf(buf,msg,ap); va_end(ap); TCOD_parser_error(buf); } // default parser bool TCODParser::hasProperty(const char *name) const { return TCOD_parser_has_property(data,name) != 0; } bool TCODParser::getBoolProperty(const char *name) const { return TCOD_parser_get_bool_property(data,name) != 0; } int TCODParser::getIntProperty(const char *name) const { return TCOD_parser_get_int_property(data,name); } int TCODParser::getCharProperty(const char *name) const { return TCOD_parser_get_char_property(data,name); } float TCODParser::getFloatProperty(const char *name) const { return TCOD_parser_get_float_property(data,name); } TCODColor TCODParser::getColorProperty(const char *name) const { return TCOD_parser_get_color_property(data,name); } TCOD_dice_t TCODParser::getDiceProperty(const char *name) const { return TCOD_parser_get_dice_property(data,name); } const char * TCODParser::getStringProperty(const char *name) const { return TCOD_parser_get_string_property(data,name); } void * TCODParser::getCustomProperty(const char *name) const { return TCOD_parser_get_custom_property(data,name); } TCOD_list_t TCODParser::getListProperty(const char *name, TCOD_value_type_t type) const { return TCOD_parser_get_list_property(data,name,type); } libtcod-1.6.4+dfsg/src/parser_c.c000066400000000000000000000757431321276576200166450ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #define BIG_NAME_LEN 128 #define DEF_NAME(d) (((TCOD_struct_int_t *)d)->name) #define DEF_FLAGS(d) (((TCOD_struct_int_t *)d)->flags) #define DEF_PROPS(d) (((TCOD_struct_int_t *)d)->props) #define DEF_LISTS(d) (((TCOD_struct_int_t *)d)->lists) /* definition property */ typedef struct { char *name; TCOD_value_type_t value; bool mandat; } TCOD_struct_prop_t; static TCOD_lex_t *lex=NULL; static const char *symbols[] = { "{","}","=","/","+","-","[","]",",","#",NULL }; static const char *keywords[] = { "struct","bool","char","int","float","string","color","dice",NULL }; static TCOD_parser_listener_t *listener=NULL; static bool default_new_struct(TCOD_parser_struct_t str,const char *name); static bool default_new_flag(const char *name); static bool default_new_property(const char *propname, TCOD_value_type_t type, TCOD_value_t value); static bool default_end_struct(TCOD_parser_struct_t str, const char *name); static void default_error(const char *msg); static TCOD_parser_listener_t default_listener = { default_new_struct, default_new_flag, default_new_property, default_end_struct, default_error }; static bool string_copy(char *dest, char *source, int len) { if ( source == NULL ) return false; strncpy(dest,source,len); dest[len-1]='\0'; if ( strlen(source) >= (unsigned)len ) return false; return true; } void TCOD_parser_error(const char *msg, ...) { char buf[2048]; char buf2[2048]; va_list ap; va_start(ap,msg); vsprintf(buf,msg,ap); va_end(ap); sprintf(buf2,"error in %s line %d : %s",lex->filename,lex->file_line,buf); listener->error(buf2); lex->token_type = TCOD_LEX_ERROR; } const char *TCOD_struct_get_name(TCOD_parser_struct_t def) { return ((TCOD_struct_int_t *)def)->name; } /* add a property to an entity definition */ void TCOD_struct_add_property(TCOD_parser_struct_t def,const char *name,TCOD_value_type_t type, bool mandatory) { TCOD_struct_prop_t *prop=(TCOD_struct_prop_t *)calloc(1,sizeof(TCOD_struct_prop_t)); prop->name=TCOD_strdup(name); prop->value=type; prop->mandat=mandatory; TCOD_list_push(DEF_PROPS(def),(void *)prop); } /* add a list property to an entity definition */ void TCOD_struct_add_list_property(TCOD_parser_struct_t def,const char *name,TCOD_value_type_t type, bool mandatory) { TCOD_struct_add_property(def,name,type|TCOD_TYPE_LIST,mandatory); } void TCOD_struct_add_value_list_sized(TCOD_parser_struct_t def,const char *name, const char **value_list, int size, bool mandatory) { char ** newArray = NULL; /* duplicate value list to avoid issues with C# garbage collector */ TCOD_value_type_t type = (TCOD_value_type_t)((int)TCOD_TYPE_VALUELIST00 + TCOD_list_size(DEF_LISTS(def))); int i = 0; if(size) newArray = calloc(size+1, sizeof(char*)); for(i = 0 ; i < size ; i++) newArray[i] = TCOD_strdup(value_list[i]); newArray[size] = NULL; TCOD_struct_add_property(def,name,type,mandatory); TCOD_list_push(DEF_LISTS(def),(void *)newArray); } /* add a value-list property to an entity definition */ void TCOD_struct_add_value_list(TCOD_parser_struct_t def,const char *name, const char **value_list, bool mandatory) { int size = 0; if(value_list) { while(value_list[size] != NULL) { size++; }; } TCOD_struct_add_value_list_sized(def, name, value_list, size, mandatory); } /* add a flag (simplified bool value) to an entity definition */ /* a flag cannot be mandatory. if present => true, if omitted => false */ void TCOD_struct_add_flag(TCOD_parser_struct_t def,const char *propname) { TCOD_list_push(DEF_FLAGS(def),(void *)TCOD_strdup(propname)); } /* add a sub-entity to an entity definition */ void TCOD_struct_add_structure(TCOD_parser_struct_t def, TCOD_parser_struct_t sub_definition) { TCOD_list_push(((TCOD_struct_int_t *)def)->structs,(const void *)sub_definition); } /* check if given property is mandatory for this entity definition */ bool TCOD_struct_is_mandatory(TCOD_parser_struct_t def, const char *propname) { TCOD_struct_prop_t **iprop; for (iprop=(TCOD_struct_prop_t **)TCOD_list_begin(DEF_PROPS(def)); iprop!=(TCOD_struct_prop_t **)TCOD_list_end(DEF_PROPS(def));iprop++) { if ( strcmp((*iprop)->name,propname) == 0 ) return (*iprop)->mandat; } return false; } /* returns the type of given property */ /* NONE if the property does not exist */ TCOD_value_type_t TCOD_struct_get_type(TCOD_parser_struct_t def, const char *propname) { TCOD_struct_prop_t **iprop; char **iflag; for (iprop=(TCOD_struct_prop_t **)TCOD_list_begin(DEF_PROPS(def)); iprop!=(TCOD_struct_prop_t **)TCOD_list_end(DEF_PROPS(def));iprop++) { if ( strcmp((*iprop)->name,propname) == 0 ) return (*iprop)->value; } for (iflag=(char **)TCOD_list_begin(DEF_FLAGS(def)); iflag!=(char **)TCOD_list_end(DEF_FLAGS(def));iflag++) { if ( strcmp((*iflag),propname) == 0 ) return TCOD_TYPE_BOOL; } return TCOD_TYPE_NONE; } TCOD_value_t TCOD_parse_bool_value(void) { TCOD_value_t ret; if ( strcmp(lex->tok,"true") == 0 ) ret.b=true; else if ( strcmp(lex->tok,"false") == 0 ) ret.b=false; else TCOD_parser_error("parseBoolValue : unknown value %s for bool. 'true' or 'false' expected",lex->tok); return ret; } TCOD_value_t TCOD_parse_char_value(void) { TCOD_value_t ret; if ( lex->token_type != TCOD_LEX_CHAR && lex->token_type != TCOD_LEX_INTEGER ) TCOD_parser_error("parseCharValue : char constant expected instead of '%s'",lex->tok); ret.c=lex->token_int_val; return ret; } TCOD_value_t TCOD_parse_integer_value(void) { TCOD_value_t ret; if ( lex->token_type != TCOD_LEX_INTEGER ) TCOD_parser_error("parseIntegerValue : integer constant expected instead of '%s'",lex->tok); ret.i=lex->token_int_val; return ret; } TCOD_value_t TCOD_parse_float_value(void) { TCOD_value_t ret; if ( lex->token_type != TCOD_LEX_FLOAT && lex->token_type != TCOD_LEX_INTEGER ) TCOD_parser_error("parseFloatValue : float constant expected instead of '%s'",lex->tok); if ( lex->token_type == TCOD_LEX_FLOAT ) ret.f=lex->token_float_val; else ret.f=(float)lex->token_int_val; return ret; } TCOD_value_t TCOD_parse_string_value(void) { TCOD_value_t ret; TCOD_list_t l; bool end=false; char **s; size_t slen=0; l=TCOD_list_new(); if ( lex->token_type != TCOD_LEX_STRING ) TCOD_parser_error("parseStringValue : string constant expected instead of '%s'",lex->tok); while ( !end ) { TCOD_lex_t save; TCOD_list_push(l,(void *)TCOD_strdup(lex->tok)); TCOD_lex_savepoint(lex,&save); if (TCOD_lex_parse(lex) != TCOD_LEX_STRING) { end=true; TCOD_lex_restore(lex,&save); } } for (s=(char **)TCOD_list_begin(l); s != (char **)TCOD_list_end(l); s++ ) { slen += strlen(*s); } ret.s=(char *)calloc(sizeof(char),slen+1); for (s=(char **)TCOD_list_begin(l); s != (char **)TCOD_list_end(l); s++ ) { strcat(ret.s,*s); free(*s); } TCOD_list_delete(l); return ret; } TCOD_value_t TCOD_parse_color_value(void) { TCOD_value_t ret; if ( lex->token_type == TCOD_LEX_SYMBOL && lex->tok[0]=='#') { char tmp[128]=""; int tok=TCOD_lex_parse(lex); /* format : col = #FFFFFF */ strcat(tmp,"#"); if ( tok == TCOD_LEX_IDEN || tok == TCOD_LEX_INTEGER ) { strcat(tmp,lex->tok); strcpy(lex->tok,tmp); if ( strlen(lex->tok) < 7 && tok == TCOD_LEX_INTEGER ) { /* special case of #12AABB => symbol # + integer 12 + iden AABB */ tok=TCOD_lex_parse(lex); if ( tok == TCOD_LEX_IDEN ) { strcat(tmp,lex->tok); strcpy(lex->tok,tmp); } } lex->token_type = TCOD_LEX_STRING; } } if ( lex->token_type != TCOD_LEX_STRING ) TCOD_parser_error("parseColorValue : string constant expected instead of '%s'",lex->tok); if (lex->tok[0] == '#') { int r,g,b; if ( strlen(lex->tok) != 7 ) TCOD_parser_error("parseColorValue : bad color format. '#rrggbb' expected instead of '%s'",lex->tok); /* web format : #rrggbb */ r=(TCOD_lex_hextoint(lex->tok[1])<<4) + TCOD_lex_hextoint(lex->tok[2]); g=(TCOD_lex_hextoint(lex->tok[3])<<4) + TCOD_lex_hextoint(lex->tok[4]); b=(TCOD_lex_hextoint(lex->tok[5])<<4) + TCOD_lex_hextoint(lex->tok[6]); ret.col.r=r; ret.col.g=g; ret.col.b=b; } else { /* standard format : rrr,ggg,bbb */ char *begin=lex->tok; char *end=strchr(begin,','); bool ok=true; if (! end) ok=false; else { *end=0; ret.col.r=atoi(begin); begin=end+1; end=strchr(begin,','); if ( !end ) ok=false; else { ret.col.g=atoi(begin); begin=end+1; ret.col.b=atoi(begin); } } if (!ok) TCOD_parser_error("parseColorValue : bad color format 'rrr,ggg,bbb' expected instead of '%s'",lex->tok); } return ret; } TCOD_value_t TCOD_parse_dice_value(void) { /* dice format : [(x|*)](D|d)[(+|-)] */ TCOD_value_t ret; bool minus=false; char *begin; char *ptr; ret.dice.multiplier=1.0f; ret.dice.addsub=0.0f; begin=lex->tok; ptr=strchr(begin,'x'); if (! ptr ) ptr=strchr(begin,'*'); if ( ptr ) { /* parse multiplier */ *ptr=0; ret.dice.multiplier=(float)atof(lex->tok); begin=ptr+1; } ptr=strchr(begin,'D'); if (!ptr ) ptr=strchr(begin,'d'); if (! ptr ) TCOD_parser_error("parseDiceValue : bad dice format. [(x|*)](D|d)[(+|-)] expected instead of '%s'",lex->tok); *ptr=0; /* parse nb_rolls */ ret.dice.nb_rolls=atoi(begin); begin=ptr+1; ptr=strchr(begin,'+'); if (! ptr) { ptr = strchr(begin,'-'); if ( ptr ) minus=true; } if (ptr) *ptr=0; /* parse nb_faces */ ret.dice.nb_faces=atoi(begin); if ( ptr ) { /* parse addsub */ begin=ptr+1; ret.dice.addsub=(float)atof(begin); if ( minus ) ret.dice.addsub=-ret.dice.addsub; } return ret; } TCOD_value_t TCOD_parse_value_list_value(TCOD_struct_int_t *def,int listnum) { TCOD_value_t ret; int i=0; char *value; char **value_list=TCOD_list_get(def->lists,listnum); if ( lex->token_type != TCOD_LEX_STRING) TCOD_parser_error("parseValueListValue : string constant expected instead of '%s'",lex->tok); value= value_list[i]; while ( value ) { if ( strcmp(lex->tok,value) == 0 ) break; i++; value=value_list[i]; } if (! value ) TCOD_parser_error("parseValueListValue : incorrect value '%s'",lex->tok); ret.s = value; return ret; } TCOD_value_t TCOD_parse_property_value(TCOD_parser_int_t *parser, TCOD_parser_struct_t def, char *propname, bool list) { TCOD_value_type_t type=TCOD_struct_get_type(def,propname); TCOD_value_t ret={0}; if (! list ) type &= ~ TCOD_TYPE_LIST; if ( type & TCOD_TYPE_LIST ) { type &= ~ TCOD_TYPE_LIST; if ( strcmp(lex->tok,"[") != 0 ) { TCOD_parser_error("'[' expected for list value instead of '%s'",lex->tok); } ret.list=TCOD_list_new(); do { TCOD_value_t val; int tok=TCOD_lex_parse(lex); if ( tok == TCOD_LEX_EOF || tok == TCOD_LEX_ERROR ) { TCOD_parser_error("Missing ']' in list value"); } val=TCOD_parse_property_value(parser,def,propname,false); if ( type == TCOD_TYPE_STRING || (type >= TCOD_TYPE_VALUELIST00 && type <= TCOD_TYPE_VALUELIST15 ) ) { TCOD_list_push(ret.list,TCOD_strdup(val.s)); } else { TCOD_list_push(ret.list,val.custom); } TCOD_lex_parse(lex); if ( strcmp(lex->tok,",") != 0 && strcmp(lex->tok,"]") != 0 ) { TCOD_parser_error("',' or ']' expected in list value instead of '%s'",lex->tok); } } while ( strcmp(lex->tok,"]") != 0 ); } else { switch (type) { case TCOD_TYPE_BOOL : return TCOD_parse_bool_value(); break; case TCOD_TYPE_CHAR : return TCOD_parse_char_value(); break; case TCOD_TYPE_INT : return TCOD_parse_integer_value(); break; case TCOD_TYPE_FLOAT : return TCOD_parse_float_value(); break; case TCOD_TYPE_STRING : return TCOD_parse_string_value(); break; case TCOD_TYPE_COLOR : return TCOD_parse_color_value(); break; case TCOD_TYPE_DICE : return TCOD_parse_dice_value(); break; case TCOD_TYPE_VALUELIST00 : case TCOD_TYPE_VALUELIST01 : case TCOD_TYPE_VALUELIST02 : case TCOD_TYPE_VALUELIST03 : case TCOD_TYPE_VALUELIST04 : case TCOD_TYPE_VALUELIST05 : case TCOD_TYPE_VALUELIST06 : case TCOD_TYPE_VALUELIST07 : case TCOD_TYPE_VALUELIST08 : case TCOD_TYPE_VALUELIST09 : case TCOD_TYPE_VALUELIST10 : case TCOD_TYPE_VALUELIST11 : case TCOD_TYPE_VALUELIST12 : case TCOD_TYPE_VALUELIST13 : case TCOD_TYPE_VALUELIST14 : case TCOD_TYPE_VALUELIST15 : { int listnum = type - TCOD_TYPE_VALUELIST00; return TCOD_parse_value_list_value((TCOD_struct_int_t *)def,listnum); break; } case TCOD_TYPE_CUSTOM00 : case TCOD_TYPE_CUSTOM01 : case TCOD_TYPE_CUSTOM02 : case TCOD_TYPE_CUSTOM03 : case TCOD_TYPE_CUSTOM04 : case TCOD_TYPE_CUSTOM05 : case TCOD_TYPE_CUSTOM06 : case TCOD_TYPE_CUSTOM07 : case TCOD_TYPE_CUSTOM08 : case TCOD_TYPE_CUSTOM09 : case TCOD_TYPE_CUSTOM10 : case TCOD_TYPE_CUSTOM11 : case TCOD_TYPE_CUSTOM12 : case TCOD_TYPE_CUSTOM13 : case TCOD_TYPE_CUSTOM14 : case TCOD_TYPE_CUSTOM15 : if ( parser->customs[type - TCOD_TYPE_CUSTOM00] ) { return parser->customs[type-TCOD_TYPE_CUSTOM00](lex,listener,def,propname); } else { TCOD_parser_error("parse_property_value : no custom parser for property type %d for entity %s prop %s", type,DEF_NAME(def),propname); } break; default : TCOD_parser_error("parse_property_value : unknown property type %d for entity %s prop %s", type,DEF_NAME(def),propname); break; } } return ret; } static bool TCOD_parser_parse_entity(TCOD_parser_int_t *parser, TCOD_struct_int_t *def) { char *name=NULL; if ( TCOD_lex_parse(lex) == TCOD_LEX_STRING ) { /* entity type name */ name=TCOD_strdup(lex->tok); TCOD_lex_parse(lex); } if ( strcmp(lex->tok,"{") != 0 ) { TCOD_parser_error("Parser::parseEntity : '{' expected"); return false; } TCOD_lex_parse(lex); while ( strcmp(lex->tok,"}") != 0 ) { bool found=false; char **iflag; bool dynStruct=false; TCOD_value_type_t dynType = TCOD_TYPE_NONE; if ( lex->token_type == TCOD_LEX_KEYWORD ) { /* dynamic property declaration */ if ( strcmp(lex->tok,"bool") == 0 ) dynType=TCOD_TYPE_BOOL; else if ( strcmp(lex->tok,"char") == 0 ) dynType=TCOD_TYPE_CHAR; else if ( strcmp(lex->tok,"int") == 0 ) dynType=TCOD_TYPE_INT; else if ( strcmp(lex->tok,"float") == 0 ) dynType=TCOD_TYPE_FLOAT; else if ( strcmp(lex->tok,"string") == 0 ) dynType=TCOD_TYPE_STRING; else if ( strcmp(lex->tok,"color") == 0 ) dynType=TCOD_TYPE_COLOR; else if ( strcmp(lex->tok,"dice") == 0 ) dynType=TCOD_TYPE_DICE; else if ( strcmp(lex->tok,"struct") == 0 ) dynStruct=true; else { TCOD_parser_error("Parser::parseEntity : dynamic declaration of '%s' not supported",lex->tok); return false; } /* TODO : dynamically declared sub-structures */ TCOD_lex_parse(lex); if ( strcmp(lex->tok,"[") == 0 ) { if ( dynType == TCOD_TYPE_NONE ) { TCOD_parser_error("Parser::parseEntity : unexpected symbol '['"); return false; } TCOD_lex_parse(lex); if ( strcmp(lex->tok,"]") != 0 ) { TCOD_parser_error("Parser::parseEntity : syntax error. ']' expected instead of '%s'",lex->tok); return false; } dynType |= TCOD_TYPE_LIST; TCOD_lex_parse(lex); } } /* parse entity type content */ if ( lex->token_type != TCOD_LEX_IDEN ) { TCOD_parser_error("Parser::parseEntity : identifier expected"); return false; } /* is it a flag ? */ if (! dynStruct && dynType == TCOD_TYPE_NONE) { for (iflag=(char **)TCOD_list_begin(def->flags);iflag!=(char **)TCOD_list_end(def->flags); iflag++) { if ( strcmp(*iflag,lex->tok) == 0 ) { found=true; if (!listener->new_flag(lex->tok)) return false; break; } } } if (!found && ! dynStruct) { do { /* is it a property ? */ TCOD_struct_prop_t **iprop; for (iprop=(TCOD_struct_prop_t **)TCOD_list_begin(def->props); iprop!=(TCOD_struct_prop_t **)TCOD_list_end(def->props);iprop++) { if ( strcmp((*iprop)->name,lex->tok) == 0 ) { char propname[BIG_NAME_LEN]; string_copy(propname,lex->tok,BIG_NAME_LEN); TCOD_lex_parse(lex); if ( strcmp(lex->tok,"=") != 0 ) { TCOD_parser_error("Parser::parseEntity : '=' expected"); return false; } TCOD_lex_parse(lex); if (!listener->new_property(propname,TCOD_struct_get_type(def,propname), TCOD_parse_property_value(parser, (TCOD_parser_struct_t *)def,propname,true))) return false; if ( lex->token_type == TCOD_LEX_ERROR ) return false; found=true; break; } } if ( !found && dynType != TCOD_TYPE_NONE ) { /* dynamically add a property to the current structure */ TCOD_struct_add_property(def,lex->tok,dynType,false); } } while ( ! found && dynType != TCOD_TYPE_NONE); } if (! found ) { /* is it a sub-entity type */ char id[BIG_NAME_LEN*2 + 2]; bool blockFound=false; do { TCOD_lex_t save; char type[BIG_NAME_LEN]; char *subname=NULL; bool named=false; TCOD_lex_savepoint(lex,&save); string_copy(type,lex->tok,BIG_NAME_LEN); strcpy(id,type); if ( TCOD_lex_parse(lex) == TCOD_LEX_STRING ) { /* # */ TCOD_struct_int_t **sub; strcat(id,"#"); strcat(id,lex->tok); named=true; subname=TCOD_strdup(lex->tok); TCOD_lex_restore(lex,&save); for ( sub = (TCOD_struct_int_t **)TCOD_list_begin(def->structs); sub != (TCOD_struct_int_t **)TCOD_list_end(def->structs); sub ++ ) { if ( strcmp((*sub)->name,id) == 0 ) { if (!listener->new_struct((TCOD_parser_struct_t *)(*sub),lex->tok)) return false; if (!TCOD_parser_parse_entity(parser,*sub)) return false; blockFound=true; found=true; break; } } } else { TCOD_lex_restore(lex,&save); } if (! blockFound ) { /* alone */ TCOD_struct_int_t **sub; for ( sub = (TCOD_struct_int_t **)TCOD_list_begin(def->structs); sub != (TCOD_struct_int_t **)TCOD_list_end(def->structs); sub ++ ) { if ( strcmp((*sub)->name,type) == 0 ) { if (!listener->new_struct((TCOD_parser_struct_t *)(*sub),subname)) return false; if (!TCOD_parser_parse_entity(parser,*sub)) return false; blockFound=true; found=true; break; } } } if (! blockFound && dynStruct ) { /* unknown structure. auto-declaration */ TCOD_struct_int_t **idef; TCOD_struct_int_t *s=NULL; for (idef=(TCOD_struct_int_t **)TCOD_list_begin(parser->structs); idef!=(TCOD_struct_int_t **)TCOD_list_end(parser->structs); idef ++) { if ( strcmp((*idef)->name,id) == 0 ) { s=*idef; break; } } if ( s == NULL && named ) { /* look for general definition for entity # */ for (idef=(TCOD_struct_int_t **)TCOD_list_begin(parser->structs); idef!=(TCOD_struct_int_t **)TCOD_list_end(parser->structs); idef ++) { if ( strcmp((*idef)->name,type) == 0 ) { s=*idef; break; } } } if ( s == NULL ) { /* dyn struct not found. create it */ s = TCOD_parser_new_struct(parser,type); } TCOD_struct_add_structure(def,s); } } while (!blockFound && dynStruct ); if (! blockFound ) { TCOD_parser_error("Parser::parseEntity : entity type %s does not contain %s", def->name,id); return false; } } TCOD_lex_parse(lex); } if (!listener->end_struct((TCOD_parser_struct_t *)def,name)) return false; return true; } /****************************************/ /* generic parser */ /****************************************/ TCOD_parser_t TCOD_parser_new(void) { TCOD_parser_int_t *ent = (TCOD_parser_int_t*)calloc(1,sizeof(TCOD_parser_int_t)); ent->structs=TCOD_list_new(); return (TCOD_parser_t) ent; } TCOD_value_type_t TCOD_parser_new_custom_type(TCOD_parser_t parser, TCOD_parser_custom_t custom_type_parser) { TCOD_parser_int_t *p=(TCOD_parser_int_t *)parser; TCOD_value_type_t type= TCOD_TYPE_CUSTOM00; while ( p->customs[ type - TCOD_TYPE_CUSTOM00 ] && type < TCOD_TYPE_CUSTOM15 ) type=(TCOD_value_type_t)(type+1); if ( p->customs[ type - TCOD_TYPE_CUSTOM00 ] ) { /* no more custom types slots available */ return TCOD_TYPE_NONE; } p->customs[type - TCOD_TYPE_CUSTOM00] = custom_type_parser; return type; } TCOD_parser_struct_t TCOD_parser_new_struct(TCOD_parser_t parser, char *name) { TCOD_struct_int_t *ent = (TCOD_struct_int_t*)calloc(1,sizeof(TCOD_struct_int_t)); ent->name=TCOD_strdup(name); ent->flags=TCOD_list_new(); ent->props=TCOD_list_new(); ent->lists=TCOD_list_new(); ent->structs=TCOD_list_new(); TCOD_list_push(((TCOD_parser_int_t *)parser)->structs,ent); return (TCOD_parser_struct_t )ent; } void TCOD_parser_delete(TCOD_parser_t parser) { TCOD_parser_int_t *p=(TCOD_parser_int_t *)parser; TCOD_struct_int_t **idef; TCOD_struct_prop_t **propCleanup; char *** listCleanup; int listSize = 0; for (idef=(TCOD_struct_int_t **)TCOD_list_begin(p->structs); idef!= (TCOD_struct_int_t **)TCOD_list_end(p->structs); idef++) { free((*idef)->name); for ( propCleanup = (TCOD_struct_prop_t**) TCOD_list_begin((*idef)->props); propCleanup != (TCOD_struct_prop_t**)TCOD_list_end((*idef)->props); propCleanup++ ) { free((*propCleanup)->name); } TCOD_list_clear_and_delete((*idef)->props); for ( listCleanup = (char ***) TCOD_list_begin((*idef)->lists); listCleanup != (char ***)TCOD_list_end((*idef)->lists); listCleanup++ ) { while((*listCleanup)[listSize] != NULL) { free((*listCleanup)[listSize]); listSize++; } } TCOD_list_clear_and_delete((*idef)->lists); } TCOD_list_clear_and_delete(p->structs); } /* parse a file */ static TCOD_list_t *default_props; /* triggers callbacks in the listener for each event during parsing */ void TCOD_parser_run(TCOD_parser_t parser, const char *filename, TCOD_parser_listener_t *_listener) { TCOD_parser_int_t *p=(TCOD_parser_int_t *)parser; if (! _listener && ! p->props ) p->props=TCOD_list_new(); listener=_listener ? _listener : &default_listener; default_props = p->props; lex=TCOD_lex_new(symbols,keywords,"//","/*","*/",NULL,"\"",TCOD_LEX_FLAG_NESTING_COMMENT); if (!TCOD_lex_set_data_file(lex,(char *)filename)) { char buf[1024]; sprintf(buf,"Fatal error : %s\n",TCOD_lex_get_last_error()); listener->error(buf); return; } while (1) { bool named=false; char id[ BIG_NAME_LEN*2 + 2 ]; char type[ BIG_NAME_LEN ]; TCOD_lex_t save; TCOD_struct_int_t *def=NULL; TCOD_struct_int_t **idef; bool dynStruct=false; TCOD_lex_parse(lex); if ( lex->token_type == TCOD_LEX_EOF || lex->token_type == TCOD_LEX_ERROR ) break; if ( lex->token_type == TCOD_LEX_KEYWORD ) { if ( strcmp(lex->tok,"struct") == 0) { /* level 0 dynamic structure declaration */ dynStruct=true; TCOD_lex_parse(lex); } else { TCOD_parser_error("Parser::parse : unexpected keyword '%s'",lex->tok); return; } } /* get entity type */ if ( lex->token_type != TCOD_LEX_IDEN ) { TCOD_parser_error("Parser::parse : identifier token expected"); return; } string_copy(type,lex->tok,BIG_NAME_LEN); strcpy(id,type); TCOD_lex_savepoint(lex,&save); if ( TCOD_lex_parse(lex) == TCOD_LEX_STRING ) { /* named entity. id = # */ strcat(id,"#"); if ( strlen(lex->tok) >= BIG_NAME_LEN ) { TCOD_parser_error("Parser::parse : name %s too long. Max %d characters", lex->tok,BIG_NAME_LEN-1); return; } strcat(id,lex->tok); named=true; } TCOD_lex_restore(lex,&save); do { /* look for a definition for id */ for (idef=(TCOD_struct_int_t **)TCOD_list_begin(p->structs); idef!=(TCOD_struct_int_t **)TCOD_list_end(p->structs); idef ++) { if ( strcmp((*idef)->name,id) == 0 ) { def=*idef; break; } } if ( def == NULL && named ) { /* look for general definition for entity # */ for (idef=(TCOD_struct_int_t **)TCOD_list_begin(p->structs); idef!=(TCOD_struct_int_t **)TCOD_list_end(p->structs); idef ++) { if ( strcmp((*idef)->name,type) == 0 ) { def=(*idef); break; } } } if ( def == NULL && dynStruct ) { /* dyn struct not found. create it */ TCOD_parser_new_struct(parser,type); } } while ( def == NULL && dynStruct ); if (def == NULL ) { TCOD_parser_error("Parser::parse : unknown entity type %s",type); return; } else { if (!listener->new_struct((TCOD_parser_struct_t)def,named ? strchr(id,'#')+1 : NULL )) return; if (!TCOD_parser_parse_entity(p,def)) return; } } if (lex->token_type == TCOD_LEX_ERROR) { TCOD_parser_error("Parser::parse : error while parsing"); return; } TCOD_lex_delete(lex); } /* default parser listener */ typedef struct { char *name; TCOD_value_type_t type; TCOD_value_t value; } prop_t; static char cur_prop_name[512]=""; static bool default_new_struct(TCOD_parser_struct_t str,const char *name) { if ( cur_prop_name[0] ) strcat(cur_prop_name,"."); strcat(cur_prop_name,((TCOD_struct_int_t *)str)->name); return true; } static bool default_new_flag(const char *name) { char tmp[512]; prop_t *prop=(prop_t *)calloc(sizeof(prop_t),1); sprintf(tmp,"%s.%s",cur_prop_name,name); prop->name=TCOD_strdup(tmp); prop->type=TCOD_TYPE_BOOL; prop->value.b=true; TCOD_list_push(default_props,prop); return true; } static bool default_new_property(const char *propname, TCOD_value_type_t type, TCOD_value_t value) { char tmp[512]; prop_t *prop=(prop_t *)calloc(sizeof(prop_t),1); sprintf(tmp,"%s.%s",cur_prop_name,propname); prop->name=TCOD_strdup(tmp); prop->type=type; prop->value=value; TCOD_list_push(default_props,prop); return true; } static bool default_end_struct(TCOD_parser_struct_t str, const char *name) { char *ptr=strrchr(cur_prop_name,'.'); if ( ptr ) *ptr='\0'; else cur_prop_name[0]='\0'; return true; } static void default_error(const char *msg) { TCOD_fatal_nopar(msg); } static const TCOD_value_t * TCOD_get_property(TCOD_parser_t parser, TCOD_value_type_t expectedType, const char *name) { void **it; char tmp[512],err[512]; char *ptr,*curname; TCOD_struct_int_t *str=NULL; TCOD_value_type_t type; TCOD_parser_int_t *p=(TCOD_parser_int_t *)parser; if (! p->props ) return NULL; for (it=TCOD_list_begin(p->props);it!=TCOD_list_end(p->props);it++) { prop_t *prop=*((prop_t **)it); if (strcmp(prop->name,name) == 0 ) { /* property found. check type */ if ( expectedType == TCOD_TYPE_STRING && prop->type >= TCOD_TYPE_VALUELIST00 && prop->type <= TCOD_TYPE_VALUELIST15 ) return &prop->value; if ( expectedType == TCOD_TYPE_CUSTOM00 && prop->type >= TCOD_TYPE_CUSTOM00 && prop->type <= TCOD_TYPE_CUSTOM15 ) return &prop->value; if (prop->type != expectedType ) { sprintf(err,"Fatal error ! Try to read property '%s' width bad type\n",name); default_error(err); } return &prop->value; } } /* property not found. Check if it exists */ strcpy(tmp,name); ptr=strchr(tmp,'.'); curname=tmp; sprintf(err,"Fatal error ! Try to read unknown property '%s'\n",name); while ( ptr ) { bool found=false; *ptr=0; for (it=TCOD_list_begin(p->structs);!found && it!=TCOD_list_end(p->structs);it++) { str=*((TCOD_struct_int_t **)it); if ( strcmp(str->name,curname) == 0 ) found=true; } if ( ! found ) { /* one of the structures is unknown */ default_error(err); } curname=ptr+1; ptr=strchr(curname,'.'); } if ( ! str ) { /* no structure in name */ default_error(err); } type = TCOD_struct_get_type((TCOD_parser_struct_t) str, curname); if ( type == TCOD_TYPE_NONE ) { /* property does not exist in structure */ default_error(err); } /* optional property not defined in the file => ok */ return NULL; } bool TCOD_parser_has_property(TCOD_parser_t parser, const char *name) { void **it; TCOD_parser_int_t *p=(TCOD_parser_int_t *)parser; if (! p->props ) return false; for (it=TCOD_list_begin(p->props);it!=TCOD_list_end(p->props);it++) { prop_t *prop=*((prop_t **)it); if (strcmp(prop->name,name) == 0 ) { return true; } } return false; } bool TCOD_parser_get_bool_property(TCOD_parser_t parser, const char *name) { const TCOD_value_t *value=TCOD_get_property(parser,TCOD_TYPE_BOOL,name); return value ? value->b : false; } int TCOD_parser_get_int_property(TCOD_parser_t parser, const char *name) { const TCOD_value_t *value=TCOD_get_property(parser,TCOD_TYPE_INT,name); return value ? value->i : 0; } int TCOD_parser_get_char_property(TCOD_parser_t parser, const char *name) { const TCOD_value_t *value=TCOD_get_property(parser,TCOD_TYPE_CHAR,name); return value ? value->c : 0; } float TCOD_parser_get_float_property(TCOD_parser_t parser, const char *name) { const TCOD_value_t *value=TCOD_get_property(parser,TCOD_TYPE_FLOAT,name); return value ? value->f : 0.0f; } const char * TCOD_parser_get_string_property(TCOD_parser_t parser, const char *name) { const TCOD_value_t *value=TCOD_get_property(parser,TCOD_TYPE_STRING,name); return value ? value->s : NULL; } TCOD_color_t TCOD_parser_get_color_property(TCOD_parser_t parser, const char *name) { const TCOD_value_t *value=TCOD_get_property(parser,TCOD_TYPE_COLOR,name); return value ? value->col : TCOD_black; } TCOD_dice_t TCOD_parser_get_dice_property(TCOD_parser_t parser, const char *name) { static TCOD_dice_t default_dice={0,0,0.0f,0.0f}; const TCOD_value_t *value=TCOD_get_property(parser,TCOD_TYPE_DICE,name); return value ? value->dice : default_dice; } void TCOD_parser_get_dice_property_py(TCOD_parser_t parser, const char *name, TCOD_dice_t *dice) { *dice=TCOD_parser_get_dice_property(parser,name); } void * TCOD_parser_get_custom_property(TCOD_parser_t parser, const char *name) { const TCOD_value_t *value=TCOD_get_property(parser,TCOD_TYPE_CUSTOM00,name); return value ? value->custom : NULL; } TCOD_list_t TCOD_parser_get_list_property(TCOD_parser_t parser, const char *name, TCOD_value_type_t type) { static TCOD_list_t empty_list=NULL; const TCOD_value_t *value; if (! empty_list ) empty_list=TCOD_list_new(); value=TCOD_get_property(parser,TCOD_TYPE_LIST|type,name); return value ? value->list : empty_list; } libtcod-1.6.4+dfsg/src/path.cpp000066400000000000000000000104351321276576200163260ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include TCODPath::TCODPath(const TCODMap *map, float diagonalCost) { data=(void *)TCOD_path_new_using_map(map->data,diagonalCost); } TCODPath::~TCODPath() { TCOD_path_delete(data); } float TCOD_path_func(int xFrom, int yFrom, int xTo,int yTo, void *data) { TCODPath::WrapperData *cppData=(TCODPath::WrapperData *)data; return cppData->listener->getWalkCost(xFrom,yFrom,xTo,yTo,cppData->userData); } TCODPath::TCODPath(int width, int height, const ITCODPathCallback *listener, void *userData, float diagonalCost) { cppData.listener=listener; cppData.userData=userData; data=(void *)TCOD_path_new_using_function(width, height, TCOD_path_func, (void *)&cppData,diagonalCost); } bool TCODPath::compute(int ox, int oy, int dx, int dy) { return TCOD_path_compute(data,ox,oy,dx,dy) != 0; } bool TCODPath::walk(int *x, int *y, bool recalculateWhenNeeded) { return TCOD_path_walk(data,x,y,recalculateWhenNeeded) != 0; } bool TCODPath::isEmpty() const { return TCOD_path_is_empty(data) != 0; } void TCODPath::reverse() { TCOD_path_reverse(data); } int TCODPath::size() const { return TCOD_path_size(data); } void TCODPath::get(int index, int *x, int *y) const { return TCOD_path_get(data,index,x,y); } void TCODPath::getOrigin(int *x,int *y) const { TCOD_path_get_origin(data,x,y); } void TCODPath::getDestination(int *x,int *y) const { TCOD_path_get_destination(data,x,y); } // ----------------- // // Dijkstra // // written by Mingos // // ----------------- // //ctor TCODDijkstra::TCODDijkstra (TCODMap *map, float diagonalCost) { data = TCOD_dijkstra_new(map->data,diagonalCost); } //another ctor TCODDijkstra::TCODDijkstra (int width, int height, const ITCODPathCallback *listener, void *userData, float diagonalCost) { cppData.listener=listener; cppData.userData=userData; data=(void *)TCOD_dijkstra_new_using_function(width, height, TCOD_path_func, (void *)&cppData,diagonalCost); } //dtor TCODDijkstra::~TCODDijkstra (void) { TCOD_dijkstra_delete(data); } //compute distances grid void TCODDijkstra::compute (int rootX, int rootY) { TCOD_dijkstra_compute(data,rootX,rootY); } //retrieve distance to a given cell float TCODDijkstra::getDistance (int x, int y) { return TCOD_dijkstra_get_distance(data,x,y); } //create a path bool TCODDijkstra::setPath (int toX, int toY) { return (TCOD_dijkstra_path_set(data,toX,toY) != 0); } void TCODDijkstra::reverse() { TCOD_dijkstra_reverse(data); } //walk a path bool TCODDijkstra::walk (int *x, int *y) { return TCOD_dijkstra_path_walk(data,x,y) != 0; } bool TCODDijkstra::isEmpty() const { return TCOD_dijkstra_is_empty(data) != 0; } int TCODDijkstra::size() const { return TCOD_dijkstra_size(data); } void TCODDijkstra::get(int index, int *x, int *y) const { return TCOD_dijkstra_get(data,index,x,y); } libtcod-1.6.4+dfsg/src/path_c.c000066400000000000000000000576711321276576200163050ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include enum { NORTH_WEST,NORTH, NORTH_EAST, WEST,NONE,EAST, SOUTH_WEST,SOUTH,SOUTH_EAST }; typedef unsigned char dir_t; /* convert dir_t to dx,dy */ static int dirx[]={-1,0,1,-1,0,1,-1,0,1}; static int diry[]={-1,-1,-1,0,0,0,1,1,1}; static int invdir[] = {SOUTH_EAST,SOUTH,SOUTH_WEST,EAST,NONE,WEST,NORTH_EAST,NORTH,NORTH_WEST}; typedef struct { int ox,oy; /* coordinates of the creature position */ int dx,dy; /* coordinates of the creature's destination */ TCOD_list_t path; /* list of dir_t to follow the path */ int w,h; /* map size */ float *grid; /* wxh djikstra distance grid (covered distance) */ float *heur; /* wxh A* score grid (covered distance + estimated remaining distance) */ dir_t *prev; /* wxh 'previous' grid : direction to the previous cell */ float diagonalCost; TCOD_list_t heap; /* min_heap used in the algorithm. stores the offset in grid/heur (offset=x+y*w) */ TCOD_map_t map; TCOD_path_func_t func; void *user_data; } TCOD_path_data_t; /* small layer on top of TCOD_list_t to implement a binary heap (min_heap) */ static void heap_sift_down(TCOD_path_data_t *path, TCOD_list_t heap) { /* sift-down : move the first element of the heap down to its right place */ int cur=0; int end = TCOD_list_size(heap)-1; int child=1; uintptr_t *array=(uintptr_t *)TCOD_list_begin(heap); while ( child <= end ) { int toSwap=cur; uintptr_t off_cur=array[cur]; float cur_dist=path->heur[off_cur]; float swapValue=cur_dist; uintptr_t off_child=array[child]; float child_dist=path->heur[off_child]; if ( child_dist < cur_dist ) { toSwap=child; swapValue=child_dist; } if ( child < end ) { /* get the min between child and child+1 */ uintptr_t off_child2=array[child+1]; float child2_dist=path->heur[off_child2]; if ( swapValue > child2_dist ) { toSwap=child+1; swapValue=child2_dist; } } if ( toSwap != cur ) { /* get down one level */ uintptr_t tmp = array[toSwap]; array[toSwap]=array[cur]; array[cur]=tmp; cur=toSwap; } else return; child=cur*2+1; } } static void heap_sift_up(TCOD_path_data_t *path, TCOD_list_t heap) { /* sift-up : move the last element of the heap up to its right place */ int end = TCOD_list_size(heap)-1; int child=end; uintptr_t *array=(uintptr_t *)TCOD_list_begin(heap); while ( child > 0 ) { uintptr_t off_child=array[child]; float child_dist=path->heur[off_child]; int parent = (child-1)/2; uintptr_t off_parent=array[parent]; float parent_dist=path->heur[off_parent]; if ( parent_dist > child_dist ) { /* get up one level */ uintptr_t tmp = array[child]; array[child]=array[parent]; array[parent]=tmp; child=parent; } else return; } } /* add a coordinate pair in the heap so that the heap root always contains the minimum A* score */ static void heap_add(TCOD_path_data_t *path, TCOD_list_t heap, int x, int y) { /* append the new value to the end of the heap */ uintptr_t off=x+y*path->w; TCOD_list_push(heap,(void *)off); /* bubble the value up to its real position */ heap_sift_up(path,heap); } /* get the coordinate pair with the minimum A* score from the heap */ static uint32_t heap_get(TCOD_path_data_t *path,TCOD_list_t heap) { /* return the first value of the heap (minimum score) */ uintptr_t *array=(uintptr_t *)TCOD_list_begin(heap); int end=TCOD_list_size(heap)-1; uint32_t off=(uint32_t)(array[0]); /* take the last element and put it at first position (heap root) */ array[0] = array[end]; TCOD_list_pop(heap); /* and bubble it down to its real position */ heap_sift_down(path,heap); return off; } /* this is the slow part, when we change the heuristic of a cell already in the heap */ static void heap_reorder(TCOD_path_data_t *path, uint32_t offset) { uintptr_t *array=(uintptr_t *)TCOD_list_begin(path->heap); uintptr_t *end=(uintptr_t *)TCOD_list_end(path->heap); uintptr_t *cur=array; uintptr_t off_idx=0; float value; int idx=0; int heap_size=TCOD_list_size(path->heap); /* find the node corresponding to offset ... SLOW !! */ while (cur != end) { if (*cur == offset ) break; cur++;idx++; } if ( cur == end ) return; off_idx=array[idx]; value=path->heur[off_idx]; if ( idx > 0 ) { int parent=(idx-1)/2; /* compare to its parent */ uintptr_t off_parent=array[parent]; float parent_value=path->heur[off_parent]; if (value < parent_value) { /* smaller. bubble it up */ while ( idx > 0 && value < parent_value ) { /* swap with parent */ array[parent]=off_idx; array[idx] = off_parent; idx=parent; if ( idx > 0 ) { parent=(idx-1)/2; off_parent=array[parent]; parent_value=path->heur[off_parent]; } } return; } } /* compare to its sons */ while ( idx*2+1 < heap_size ) { int child=idx*2+1; uintptr_t off_child=array[child]; int toSwap=idx; int child2; float swapValue=value; if ( path->heur[off_child] < value ) { /* swap with son1 ? */ toSwap=child; swapValue=path->heur[off_child]; } child2 = child+1; if ( child2 < heap_size ) { uintptr_t off_child2=array[child2]; if ( path->heur[off_child2] < swapValue) { /* swap with son2 */ toSwap=child2; } } if ( toSwap != idx ) { /* bigger. bubble it down */ uintptr_t tmp = array[toSwap]; array[toSwap]=array[idx]; array[idx] = tmp; idx=toSwap; } else return; } } /* private functions */ static void TCOD_path_push_cell(TCOD_path_data_t *path, int x, int y); static void TCOD_path_get_cell(TCOD_path_data_t *path, int *x, int *y, float *distance); static void TCOD_path_set_cells(TCOD_path_data_t *path); static float TCOD_path_walk_cost(TCOD_path_data_t *path, int xFrom, int yFrom, int xTo, int yTo); static TCOD_path_data_t *TCOD_path_new_intern(int w, int h) { TCOD_path_data_t *path=(TCOD_path_data_t *)calloc(sizeof(TCOD_path_data_t),1); path->w=w; path->h=h; path->grid=(float *)calloc(sizeof(float),w*h); path->heur=(float *)calloc(sizeof(float),w*h); path->prev=(dir_t *)calloc(sizeof(dir_t),w*h); if (! path->grid || ! path->heur || ! path->prev ) { TCOD_fatal("Fatal error : path finding module cannot allocate djikstra grids (size %dx%d)\n",w,h); exit(1); } path->path=TCOD_list_new(); path->heap=TCOD_list_new(); return path; } TCOD_path_t TCOD_path_new_using_map(TCOD_map_t map, float diagonalCost) { TCOD_path_data_t *path; TCOD_IFNOT(map != NULL) return NULL; path=TCOD_path_new_intern(TCOD_map_get_width(map),TCOD_map_get_height(map)); path->map=map; path->diagonalCost=diagonalCost; return (TCOD_path_t)path; } TCOD_path_t TCOD_path_new_using_function(int map_width, int map_height, TCOD_path_func_t func, void *user_data, float diagonalCost) { TCOD_path_data_t *path; TCOD_IFNOT(func != NULL && map_width > 0 && map_height > 0) return NULL; path=TCOD_path_new_intern(map_width,map_height); path->func=func; path->user_data=user_data; path->diagonalCost=diagonalCost; return (TCOD_path_t)path; } bool TCOD_path_compute(TCOD_path_t p, int ox,int oy, int dx, int dy) { TCOD_path_data_t *path=(TCOD_path_data_t *)p; TCOD_IFNOT(p != NULL) return false; path->ox=ox; path->oy=oy; path->dx=dx; path->dy=dy; TCOD_list_clear(path->path); TCOD_list_clear(path->heap); if ( ox == dx && oy == dy ) return true; /* trivial case */ /* check that origin and destination are inside the map */ TCOD_IFNOT((unsigned)ox < (unsigned)path->w && (unsigned)oy < (unsigned)path->h) return false; TCOD_IFNOT((unsigned)dx < (unsigned)path->w && (unsigned)dy < (unsigned)path->h) return false; /* initialize djikstra grids */ memset(path->grid,0,sizeof(float)*path->w*path->h); memset(path->prev,NONE,sizeof(dir_t)*path->w*path->h); path->heur[ ox + oy * path->w ] = 1.0f; /* anything != 0 */ TCOD_path_push_cell(path,ox,oy); /* put the origin cell as a bootstrap */ /* fill the djikstra grid until we reach dx,dy */ TCOD_path_set_cells(path); if ( path->grid[dx + dy * path->w] == 0 ) return false; /* no path found */ /* there is a path. retrieve it */ do { /* walk from destination to origin, using the 'prev' array */ int step=path->prev[ dx + dy * path->w ]; TCOD_list_push(path->path,(void *)(uintptr_t)step); dx -= dirx[step]; dy -= diry[step]; } while ( dx != ox || dy != oy ); return true; } void TCOD_path_reverse(TCOD_path_t p) { int tmp,i; TCOD_path_data_t *path=(TCOD_path_data_t *)p; TCOD_IFNOT(p != NULL) return ; tmp=path->ox; path->ox=path->dx; path->dx=tmp; tmp=path->oy; path->oy=path->dy; path->dy=tmp; for (i=0; i < TCOD_list_size(path->path); i++) { int d=(int)(uintptr_t)TCOD_list_get(path->path,i); d = invdir[d]; TCOD_list_set(path->path,(void *)(uintptr_t)d,i); } } bool TCOD_path_walk(TCOD_path_t p, int *x, int *y, bool recalculate_when_needed) { int newx,newy; int d; TCOD_path_data_t *path=(TCOD_path_data_t *)p; TCOD_IFNOT(p != NULL) return false; if ( TCOD_path_is_empty(path) ) return false; d=(int)(uintptr_t)TCOD_list_pop(path->path); newx=path->ox + dirx[d]; newy=path->oy + diry[d]; /* check if the path is still valid */ if ( TCOD_path_walk_cost(path,path->ox,path->oy,newx,newy) <= 0.0f ) { /* path is blocked */ if (! recalculate_when_needed ) return false; /* don't walk */ /* calculate a new path */ if (! TCOD_path_compute(path, path->ox,path->oy, path->dx,path->dy) ) return false ; /* cannot find a new path */ return TCOD_path_walk(p,x,y,true); /* walk along the new path */ } if ( x ) *x=newx; if ( y ) *y=newy; path->ox=newx; path->oy=newy; return true; } bool TCOD_path_is_empty(TCOD_path_t p) { TCOD_path_data_t *path=(TCOD_path_data_t *)p; TCOD_IFNOT(p != NULL) return true; return TCOD_list_is_empty(path->path); } int TCOD_path_size(TCOD_path_t p) { TCOD_path_data_t *path=(TCOD_path_data_t *)p; TCOD_IFNOT(p != NULL) return 0; return TCOD_list_size(path->path); } void TCOD_path_get(TCOD_path_t p, int index, int *x, int *y) { int pos; TCOD_path_data_t *path=(TCOD_path_data_t *)p; TCOD_IFNOT(p != NULL) return; if ( x ) *x=path->ox; if ( y ) *y=path->oy; pos = TCOD_list_size(path->path)-1; do { int step=(int)(uintptr_t)TCOD_list_get(path->path,pos); if ( x ) *x += dirx[step]; if ( y ) *y += diry[step]; pos--;index--; } while (index >= 0); } void TCOD_path_delete(TCOD_path_t p) { TCOD_path_data_t *path=(TCOD_path_data_t *)p; TCOD_IFNOT(p != NULL) return; if ( path->grid ) free(path->grid); if ( path->heur ) free(path->heur); if ( path->prev ) free(path->prev); if ( path->path ) TCOD_list_delete(path->path); if ( path->heap ) TCOD_list_delete(path->heap); free(path); } /* private stuff */ /* add a new unvisited cells to the cells-to-treat list * the list is in fact a min_heap. Cell at index i has its sons at 2*i+1 and 2*i+2 */ static void TCOD_path_push_cell(TCOD_path_data_t *path, int x, int y) { heap_add(path,path->heap,x,y); } /* get the best cell from the heap */ static void TCOD_path_get_cell(TCOD_path_data_t *path, int *x, int *y, float *distance) { uint32_t offset = heap_get(path,path->heap); *x=(offset % path->w); *y=(offset / path->w); *distance=path->grid[offset]; } /* fill the grid, starting from the origin until we reach the destination */ static void TCOD_path_set_cells(TCOD_path_data_t *path) { while ( path->grid[path->dx + path->dy * path->w ] == 0 && ! TCOD_list_is_empty(path->heap) ) { int x,y,i,imax; float distance; TCOD_path_get_cell(path,&x,&y,&distance); imax= ( path->diagonalCost == 0.0f ? 4 : 8) ; for (i=0; i < imax; i++ ) { /* convert i to dx,dy */ static int idirx[]={0,-1,1,0,-1,1,-1,1}; static int idiry[]={-1,0,0,1,-1,-1,1,1}; /* convert i to direction */ static dir_t prevdirs[] = { NORTH, WEST, EAST, SOUTH, NORTH_WEST, NORTH_EAST,SOUTH_WEST,SOUTH_EAST }; /* coordinate of the adjacent cell */ int cx=x+idirx[i]; int cy=y+idiry[i]; if ( cx >= 0 && cy >= 0 && cx < path->w && cy < path->h ) { float walk_cost = TCOD_path_walk_cost(path,x,y,cx,cy); if ( walk_cost > 0.0f ) { /* in of the map and walkable */ float covered=distance + walk_cost * (i>=4 ? path->diagonalCost : 1.0f); float previousCovered = path->grid[cx + cy * path->w ]; if ( previousCovered == 0 ) { /* put a new cell in the heap */ int offset=cx + cy * path->w; /* A* heuristic : remaining distance */ float remaining=(float)sqrt((cx-path->dx)*(cx-path->dx)+(cy-path->dy)*(cy-path->dy)); path->grid[ offset ] = covered; path->heur[ offset ] = covered + remaining; path->prev[ offset ] = prevdirs[i]; TCOD_path_push_cell(path,cx,cy); } else if ( previousCovered > covered ) { /* we found a better path to a cell already in the heap */ int offset=cx + cy * path->w; path->grid[ offset ] = covered; path->heur[ offset ] -= (previousCovered - covered); /* fix the A* score */ path->prev[ offset ] = prevdirs[i]; /* reorder the heap */ heap_reorder(path,offset); } } } } } } /* check if a cell is walkable (from the pathfinder point of view) */ static float TCOD_path_walk_cost(TCOD_path_data_t *path, int xFrom, int yFrom, int xTo, int yTo) { if ( path->map ) return TCOD_map_is_walkable(path->map,xTo,yTo) ? 1.0f : 0.0f; return path->func(xFrom,yFrom,xTo,yTo,path->user_data); } void TCOD_path_get_origin(TCOD_path_t p, int *x, int *y) { TCOD_path_data_t *path=(TCOD_path_data_t *)p; TCOD_IFNOT(p != NULL) return; if ( x ) *x=path->ox; if ( y ) *y=path->oy; } void TCOD_path_get_destination(TCOD_path_t p, int *x, int *y) { TCOD_path_data_t *path=(TCOD_path_data_t *)p; TCOD_IFNOT(p != NULL) return; if ( x ) *x=path->dx; if ( y ) *y=path->dy; } /* ------------------------------------------------------- * * Dijkstra * * written by Mingos * * ----------------- * * A floodfill-like algo that will calculate all distances * * to all accessible cells (nodes) from a given root node. * * ------------------------------------------------------- */ /* Dijkstra data structure */ typedef struct { int diagonal_cost; int width, height, nodes_max; TCOD_map_t map; /* a TCODMap with walkability data */ TCOD_path_func_t func; void *user_data; unsigned int * distances; /* distances grid */ unsigned int * nodes; /* the processed nodes */ TCOD_list_t path; } dijkstra_t; /* create a Dijkstra object */ TCOD_dijkstra_t TCOD_dijkstra_new (TCOD_map_t map, float diagonalCost) { dijkstra_t * data ; TCOD_IFNOT(map != NULL) return NULL; data = malloc(sizeof(dijkstra_t)); data->map = map; data->func = NULL; data->user_data=NULL; data->distances = malloc(TCOD_map_get_nb_cells(data->map)*sizeof(int)); data->nodes = malloc(TCOD_map_get_nb_cells(data->map)*sizeof(int)); data->diagonal_cost = (int)((diagonalCost * 100.0f)+0.1f); /* because (int)(1.41f*100.0f) == 140!!! */ data->width = TCOD_map_get_width(data->map); data->height = TCOD_map_get_height(data->map); data->nodes_max = TCOD_map_get_nb_cells(data->map); data->path = TCOD_list_new(); return (TCOD_dijkstra_t)data; } TCOD_dijkstra_t TCOD_dijkstra_new_using_function(int map_width, int map_height, TCOD_path_func_t func, void *user_data, float diagonalCost) { dijkstra_t * data; TCOD_IFNOT(func != NULL && map_width > 0 && map_height > 0) return NULL; data = malloc(sizeof(dijkstra_t)); data->map = NULL; data->func = func; data->user_data=user_data; data->distances = malloc(map_width*map_height*sizeof(int)*4); data->nodes = malloc(map_width*map_height*sizeof(int)*4); data->diagonal_cost = (int)((diagonalCost * 100.0f)+0.1f); /* because (int)(1.41f*100.0f) == 140!!! */ data->width = map_width; data->height = map_height; data->nodes_max = map_width*map_height; data->path = TCOD_list_new(); return (TCOD_dijkstra_t)data; } /* compute a Dijkstra grid */ void TCOD_dijkstra_compute (TCOD_dijkstra_t dijkstra, int root_x, int root_y) { dijkstra_t * data = (dijkstra_t*)dijkstra; /* map size data */ unsigned int mx = data->width; unsigned int my = data->height; unsigned int mmax = data->nodes_max; /* encode the root coords in one integer */ unsigned int root = (root_y * mx) + root_x; /* some stuff to walk through the nodes table */ unsigned int index = 0; /* the index of the first node in queue */ unsigned int last_index = 1; /* total nb of registered queue indices */ unsigned int * nodes = data->nodes; /* table of nodes to which the indices above apply */ /* ok, here's the order of node processing: W, S, E, N, NW, NE, SE, SW */ static int dx[8] = { -1, 0, 1, 0, -1, 1, 1, -1 }; static int dy[8] = { 0, -1, 0, 1, -1, -1, 1, 1 }; /* and distances for each index */ int dd[8] = { 100, 100, 100, 100, data->diagonal_cost, data->diagonal_cost, data->diagonal_cost, data->diagonal_cost }; /* if diagonal_cost is 0, disallow diagonal moves */ int imax = (data->diagonal_cost == 0 ? 4 : 8); /* aight, now set the distances table and set everything to infinity */ unsigned int * distances = data->distances; TCOD_IFNOT(data != NULL) return; TCOD_IFNOT((unsigned)root_x < (unsigned)mx && (unsigned)root_y < (unsigned)my) return; memset(distances,0xFFFFFFFF,mmax*sizeof(int)); memset(nodes,0xFFFFFFFF,mmax*sizeof(int)); /* data for root node is known... */ distances[root] = 0; nodes[index] = root; /*set starting note to root */ /* and the loop */ do { unsigned int x, y; int i; if (nodes[index] == 0xFFFFFFFF) { continue; } /* coordinates of currently processed node */ x = nodes[index] % mx; y = nodes[index] / mx; /* check adjacent nodes */ for(i=0;imap ) dt += dd[i]; else { /* distance given by the user callback */ userDist=data->func(x,y,tx,ty,data->user_data); dt += (unsigned int)(userDist*dd[i]); } /* ..., encode coordinates, ... */ new_node = (ty * mx) + tx; /* and check if the node's eligible for queuing */ if (distances[new_node] > dt) { unsigned int j; /* if not walkable, don't process it */ if (data->map && !TCOD_map_is_walkable(data->map,tx,ty)) continue; else if ( data->func && userDist <= 0.0f ) continue; distances[new_node] = dt; /* set processed node's distance */ /* place the processed node in the queue before the last queued node with greater distance */ j = last_index - 1; while (distances[nodes[j]] >= distances[new_node]) { /* this ensures that if the node has been queued previously, but with a higher distance, it's removed */ if (nodes[j] == new_node) { int k = j; while ((unsigned)k <= last_index) { nodes[k] = nodes[k+1]; k++; } last_index--; } else nodes[j+1] = nodes[j]; j--; } last_index++; /* increase total indices count */ nodes[j+1] = new_node; /* and finally put the node where it belongs in the queue */ } } } } while (mmax > ++index); } /* get distance from source */ float TCOD_dijkstra_get_distance (TCOD_dijkstra_t dijkstra, int x, int y) { dijkstra_t * data = (dijkstra_t*)dijkstra; unsigned int * distances; TCOD_IFNOT(data != NULL) return -1.0f; TCOD_IFNOT ((unsigned)x < (unsigned)data->width && (unsigned)y < (unsigned)data->height) return -1.0f; if (data->distances[(y*data->width)+x] == 0xFFFFFFFF) return -1.0f; distances = data->distances; return ((float)distances[(y * data->width) + x] * 0.01f); } unsigned int dijkstra_get_int_distance (dijkstra_t * data, int x, int y) { unsigned int * distances = data->distances; return distances[(y * data->width) + x]; } /* create a path */ bool TCOD_dijkstra_path_set (TCOD_dijkstra_t dijkstra, int x, int y) { dijkstra_t * data = (dijkstra_t*)dijkstra; int px = x, py = y; static int dx[9] = { -1, 0, 1, 0, -1, 1, 1, -1, 0 }; static int dy[9] = { 0, -1, 0, 1, -1, -1, 1, 1, 0 }; unsigned int distances[8] = {0}; int lowest_index; int imax = (data->diagonal_cost == 0 ? 4 : 8); TCOD_IFNOT(data != NULL) return false; TCOD_IFNOT((unsigned)x < (unsigned)data->width && (unsigned)y < (unsigned)data->height) return false; /* check that destination is reachable */ if ( dijkstra_get_int_distance(data,x,y) == 0xFFFFFFFF ) return false; TCOD_list_clear(data->path); do { unsigned int lowest; int i; TCOD_list_push(data->path,(const void*)(uintptr_t)((py * data->width) + px)); for(i=0;iwidth && (unsigned)cy < (unsigned)data->height) distances[i] = dijkstra_get_int_distance(data,cx,cy); else distances[i] = 0xFFFFFFFF; } lowest = dijkstra_get_int_distance(data,px,py); lowest_index = 8; for(i=0;ipath); return true; } void TCOD_dijkstra_reverse(TCOD_dijkstra_t dijkstra) { dijkstra_t * data = (dijkstra_t*)dijkstra; TCOD_IFNOT(data != NULL) return; TCOD_list_reverse(data->path); } /* walk the path */ bool TCOD_dijkstra_path_walk (TCOD_dijkstra_t dijkstra, int *x, int *y) { dijkstra_t * data = (dijkstra_t*)dijkstra; TCOD_IFNOT(data != NULL) return false; if (TCOD_list_is_empty(data->path)) return false; else { unsigned int node = (unsigned int)(uintptr_t)TCOD_list_pop(data->path); if ( x ) *x = (int)(node % data->width); if ( y ) *y = (int)(node / data->width); } return true; } /* delete a Dijkstra object */ void TCOD_dijkstra_delete (TCOD_dijkstra_t dijkstra) { dijkstra_t * data = (dijkstra_t*)dijkstra; TCOD_IFNOT(data != NULL) return; if ( data->distances ) free(data->distances); if ( data->nodes ) free(data->nodes); if ( data->path ) TCOD_list_delete(data->path); free(data); } bool TCOD_dijkstra_is_empty(TCOD_dijkstra_t p) { dijkstra_t * data = (dijkstra_t*)p; TCOD_IFNOT(data != NULL) return true; return TCOD_list_is_empty(data->path); } int TCOD_dijkstra_size(TCOD_dijkstra_t p) { dijkstra_t * data = (dijkstra_t*)p; TCOD_IFNOT(data != NULL) return 0; return TCOD_list_size(data->path); } void TCOD_dijkstra_get(TCOD_dijkstra_t p, int index, int *x, int *y) { dijkstra_t * data = (dijkstra_t*)p; unsigned int node ; TCOD_IFNOT(data != NULL) return; node = (unsigned int)(uintptr_t)TCOD_list_get(data->path,TCOD_list_size(data->path)-index-1); if ( x ) *x = (int)(node % data->width); if ( y ) *y = (int)(node / data->width); } libtcod-1.6.4+dfsg/src/png/000077500000000000000000000000001321276576200154475ustar00rootroot00000000000000libtcod-1.6.4+dfsg/src/png/lodepng.c000066400000000000000000006561021321276576200172550ustar00rootroot00000000000000/* LodePNG version 20160501 Copyright (c) 2005-2016 Lode Vandevenne This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ /* The manual and changelog are in the header file "lodepng.h" Rename this file to lodepng.cpp to use it for C++, or to lodepng.c to use it for C. */ #include "lodepng.h" #include #include #include #if defined(_MSC_VER) && (_MSC_VER >= 1310) /*Visual Studio: A few warning types are not desired here.*/ #pragma warning( disable : 4244 ) /*implicit conversions: not warned by gcc -Wall -Wextra and requires too much casts*/ #pragma warning( disable : 4996 ) /*VS does not like fopen, but fopen_s is not standard C so unusable here*/ #endif /*_MSC_VER */ const char* LODEPNG_VERSION_STRING = "20160501"; /* This source file is built up in the following large parts. The code sections with the "LODEPNG_COMPILE_" #defines divide this up further in an intermixed way. -Tools for C and common code for PNG and Zlib -C Code for Zlib (huffman, deflate, ...) -C Code for PNG (file format chunks, adam7, PNG filters, color conversions, ...) -The C++ wrapper around all of the above */ /*The malloc, realloc and free functions defined here with "lodepng_" in front of the name, so that you can easily change them to others related to your platform if needed. Everything else in the code calls these. Pass -DLODEPNG_NO_COMPILE_ALLOCATORS to the compiler, or comment out #define LODEPNG_COMPILE_ALLOCATORS in the header, to disable the ones here and define them in your own project's source files without needing to change lodepng source code. Don't forget to remove "static" if you copypaste them from here.*/ #ifdef LODEPNG_COMPILE_ALLOCATORS static void* lodepng_malloc(size_t size) { return malloc(size); } static void* lodepng_realloc(void* ptr, size_t new_size) { return realloc(ptr, new_size); } static void lodepng_free(void* ptr) { free(ptr); } #else /*LODEPNG_COMPILE_ALLOCATORS*/ void* lodepng_malloc(size_t size); void* lodepng_realloc(void* ptr, size_t new_size); void lodepng_free(void* ptr); #endif /*LODEPNG_COMPILE_ALLOCATORS*/ /* ////////////////////////////////////////////////////////////////////////// */ /* ////////////////////////////////////////////////////////////////////////// */ /* // Tools for C, and common code for PNG and Zlib. // */ /* ////////////////////////////////////////////////////////////////////////// */ /* ////////////////////////////////////////////////////////////////////////// */ /* Often in case of an error a value is assigned to a variable and then it breaks out of a loop (to go to the cleanup phase of a function). This macro does that. It makes the error handling code shorter and more readable. Example: if(!uivector_resizev(&frequencies_ll, 286, 0)) ERROR_BREAK(83); */ #define CERROR_BREAK(errorvar, code)\ {\ errorvar = code;\ break;\ } /*version of CERROR_BREAK that assumes the common case where the error variable is named "error"*/ #define ERROR_BREAK(code) CERROR_BREAK(error, code) /*Set error var to the error code, and return it.*/ #define CERROR_RETURN_ERROR(errorvar, code)\ {\ errorvar = code;\ return code;\ } /*Try the code, if it returns error, also return the error.*/ #define CERROR_TRY_RETURN(call)\ {\ unsigned error = call;\ if(error) return error;\ } /*Set error var to the error code, and return from the void function.*/ #define CERROR_RETURN(errorvar, code)\ {\ errorvar = code;\ return;\ } /* About uivector, ucvector and string: -All of them wrap dynamic arrays or text strings in a similar way. -LodePNG was originally written in C++. The vectors replace the std::vectors that were used in the C++ version. -The string tools are made to avoid problems with compilers that declare things like strncat as deprecated. -They're not used in the interface, only internally in this file as static functions. -As with many other structs in this file, the init and cleanup functions serve as ctor and dtor. */ #ifdef LODEPNG_COMPILE_ZLIB /*dynamic vector of unsigned ints*/ typedef struct uivector { unsigned* data; size_t size; /*size in number of unsigned longs*/ size_t allocsize; /*allocated size in bytes*/ } uivector; static void uivector_cleanup(void* p) { ((uivector*)p)->size = ((uivector*)p)->allocsize = 0; lodepng_free(((uivector*)p)->data); ((uivector*)p)->data = NULL; } /*returns 1 if success, 0 if failure ==> nothing done*/ static unsigned uivector_reserve(uivector* p, size_t allocsize) { if(allocsize > p->allocsize) { size_t newsize = (allocsize > p->allocsize * 2) ? allocsize : (allocsize * 3 / 2); void* data = lodepng_realloc(p->data, newsize); if(data) { p->allocsize = newsize; p->data = (unsigned*)data; } else return 0; /*error: not enough memory*/ } return 1; } /*returns 1 if success, 0 if failure ==> nothing done*/ static unsigned uivector_resize(uivector* p, size_t size) { if(!uivector_reserve(p, size * sizeof(unsigned))) return 0; p->size = size; return 1; /*success*/ } /*resize and give all new elements the value*/ static unsigned uivector_resizev(uivector* p, size_t size, unsigned value) { size_t oldsize = p->size, i; if(!uivector_resize(p, size)) return 0; for(i = oldsize; i < size; ++i) p->data[i] = value; return 1; } static void uivector_init(uivector* p) { p->data = NULL; p->size = p->allocsize = 0; } #ifdef LODEPNG_COMPILE_ENCODER /*returns 1 if success, 0 if failure ==> nothing done*/ static unsigned uivector_push_back(uivector* p, unsigned c) { if(!uivector_resize(p, p->size + 1)) return 0; p->data[p->size - 1] = c; return 1; } #endif /*LODEPNG_COMPILE_ENCODER*/ #endif /*LODEPNG_COMPILE_ZLIB*/ /* /////////////////////////////////////////////////////////////////////////// */ /*dynamic vector of unsigned chars*/ typedef struct ucvector { unsigned char* data; size_t size; /*used size*/ size_t allocsize; /*allocated size*/ } ucvector; /*returns 1 if success, 0 if failure ==> nothing done*/ static unsigned ucvector_reserve(ucvector* p, size_t allocsize) { if(allocsize > p->allocsize) { size_t newsize = (allocsize > p->allocsize * 2) ? allocsize : (allocsize * 3 / 2); void* data = lodepng_realloc(p->data, newsize); if(data) { p->allocsize = newsize; p->data = (unsigned char*)data; } else return 0; /*error: not enough memory*/ } return 1; } /*returns 1 if success, 0 if failure ==> nothing done*/ static unsigned ucvector_resize(ucvector* p, size_t size) { if(!ucvector_reserve(p, size * sizeof(unsigned char))) return 0; p->size = size; return 1; /*success*/ } #ifdef LODEPNG_COMPILE_PNG static void ucvector_cleanup(void* p) { ((ucvector*)p)->size = ((ucvector*)p)->allocsize = 0; lodepng_free(((ucvector*)p)->data); ((ucvector*)p)->data = NULL; } static void ucvector_init(ucvector* p) { p->data = NULL; p->size = p->allocsize = 0; } #endif /*LODEPNG_COMPILE_PNG*/ #ifdef LODEPNG_COMPILE_ZLIB /*you can both convert from vector to buffer&size and vica versa. If you use init_buffer to take over a buffer and size, it is not needed to use cleanup*/ static void ucvector_init_buffer(ucvector* p, unsigned char* buffer, size_t size) { p->data = buffer; p->allocsize = p->size = size; } #endif /*LODEPNG_COMPILE_ZLIB*/ #if (defined(LODEPNG_COMPILE_PNG) && defined(LODEPNG_COMPILE_ANCILLARY_CHUNKS)) || defined(LODEPNG_COMPILE_ENCODER) /*returns 1 if success, 0 if failure ==> nothing done*/ static unsigned ucvector_push_back(ucvector* p, unsigned char c) { if(!ucvector_resize(p, p->size + 1)) return 0; p->data[p->size - 1] = c; return 1; } #endif /*defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER)*/ /* ////////////////////////////////////////////////////////////////////////// */ #ifdef LODEPNG_COMPILE_PNG #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /*returns 1 if success, 0 if failure ==> nothing done*/ static unsigned string_resize(char** out, size_t size) { char* data = (char*)lodepng_realloc(*out, size + 1); if(data) { data[size] = 0; /*null termination char*/ *out = data; } return data != 0; } /*init a {char*, size_t} pair for use as string*/ static void string_init(char** out) { *out = NULL; string_resize(out, 0); } /*free the above pair again*/ static void string_cleanup(char** out) { lodepng_free(*out); *out = NULL; } static void string_set(char** out, const char* in) { size_t insize = strlen(in), i; if(string_resize(out, insize)) { for(i = 0; i != insize; ++i) { (*out)[i] = in[i]; } } } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ #endif /*LODEPNG_COMPILE_PNG*/ /* ////////////////////////////////////////////////////////////////////////// */ unsigned lodepng_read32bitInt(const unsigned char* buffer) { return (unsigned)((buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]); } #if defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER) /*buffer must have at least 4 allocated bytes available*/ static void lodepng_set32bitInt(unsigned char* buffer, unsigned value) { buffer[0] = (unsigned char)((value >> 24) & 0xff); buffer[1] = (unsigned char)((value >> 16) & 0xff); buffer[2] = (unsigned char)((value >> 8) & 0xff); buffer[3] = (unsigned char)((value ) & 0xff); } #endif /*defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER)*/ #ifdef LODEPNG_COMPILE_ENCODER static void lodepng_add32bitInt(ucvector* buffer, unsigned value) { ucvector_resize(buffer, buffer->size + 4); /*todo: give error if resize failed*/ lodepng_set32bitInt(&buffer->data[buffer->size - 4], value); } #endif /*LODEPNG_COMPILE_ENCODER*/ /* ////////////////////////////////////////////////////////////////////////// */ /* / File IO / */ /* ////////////////////////////////////////////////////////////////////////// */ #ifdef LODEPNG_COMPILE_DISK /* returns negative value on error. This should be pure C compatible, so no fstat. */ static long lodepng_filesize(const char* filename) { FILE* file; long size; file = fopen(filename, "rb"); if(!file) return -1; if(fseek(file, 0, SEEK_END) != 0) { fclose(file); return -1; } size = ftell(file); /* It may give LONG_MAX as directory size, this is invalid for us. */ if(size == LONG_MAX) size = -1; fclose(file); return size; } /* load file into buffer that already has the correct allocated size. Returns error code.*/ static unsigned lodepng_buffer_file(unsigned char* out, size_t size, const char* filename) { FILE* file; size_t readsize; file = fopen(filename, "rb"); if(!file) return 78; readsize = fread(out, 1, size, file); fclose(file); if (readsize != size) return 78; return 0; } unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename) { long size = lodepng_filesize(filename); if (size < 0) return 78; *outsize = (size_t)size; *out = (unsigned char*)lodepng_malloc((size_t)size); if(!(*out) && size > 0) return 83; /*the above malloc failed*/ return lodepng_buffer_file(*out, (size_t)size, filename); } /*write given buffer to the file, overwriting the file, it doesn't append to it.*/ unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename) { FILE* file; file = fopen(filename, "wb" ); if(!file) return 79; fwrite((char*)buffer , 1 , buffersize, file); fclose(file); return 0; } #endif /*LODEPNG_COMPILE_DISK*/ /* ////////////////////////////////////////////////////////////////////////// */ /* ////////////////////////////////////////////////////////////////////////// */ /* // End of common code and tools. Begin of Zlib related code. // */ /* ////////////////////////////////////////////////////////////////////////// */ /* ////////////////////////////////////////////////////////////////////////// */ #ifdef LODEPNG_COMPILE_ZLIB #ifdef LODEPNG_COMPILE_ENCODER /*TODO: this ignores potential out of memory errors*/ #define addBitToStream(/*size_t**/ bitpointer, /*ucvector**/ bitstream, /*unsigned char*/ bit)\ {\ /*add a new byte at the end*/\ if(((*bitpointer) & 7) == 0) ucvector_push_back(bitstream, (unsigned char)0);\ /*earlier bit of huffman code is in a lesser significant bit of an earlier byte*/\ (bitstream->data[bitstream->size - 1]) |= (bit << ((*bitpointer) & 0x7));\ ++(*bitpointer);\ } static void addBitsToStream(size_t* bitpointer, ucvector* bitstream, unsigned value, size_t nbits) { size_t i; for(i = 0; i != nbits; ++i) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> i) & 1)); } static void addBitsToStreamReversed(size_t* bitpointer, ucvector* bitstream, unsigned value, size_t nbits) { size_t i; for(i = 0; i != nbits; ++i) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> (nbits - 1 - i)) & 1)); } #endif /*LODEPNG_COMPILE_ENCODER*/ #ifdef LODEPNG_COMPILE_DECODER #define READBIT(bitpointer, bitstream) ((bitstream[bitpointer >> 3] >> (bitpointer & 0x7)) & (unsigned char)1) static unsigned char readBitFromStream(size_t* bitpointer, const unsigned char* bitstream) { unsigned char result = (unsigned char)(READBIT(*bitpointer, bitstream)); ++(*bitpointer); return result; } static unsigned readBitsFromStream(size_t* bitpointer, const unsigned char* bitstream, size_t nbits) { unsigned result = 0, i; for(i = 0; i != nbits; ++i) { result += ((unsigned)READBIT(*bitpointer, bitstream)) << i; ++(*bitpointer); } return result; } #endif /*LODEPNG_COMPILE_DECODER*/ /* ////////////////////////////////////////////////////////////////////////// */ /* / Deflate - Huffman / */ /* ////////////////////////////////////////////////////////////////////////// */ #define FIRST_LENGTH_CODE_INDEX 257 #define LAST_LENGTH_CODE_INDEX 285 /*256 literals, the end code, some length codes, and 2 unused codes*/ #define NUM_DEFLATE_CODE_SYMBOLS 288 /*the distance codes have their own symbols, 30 used, 2 unused*/ #define NUM_DISTANCE_SYMBOLS 32 /*the code length codes. 0-15: code lengths, 16: copy previous 3-6 times, 17: 3-10 zeros, 18: 11-138 zeros*/ #define NUM_CODE_LENGTH_CODES 19 /*the base lengths represented by codes 257-285*/ static const unsigned LENGTHBASE[29] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258}; /*the extra bits used by codes 257-285 (added to base length)*/ static const unsigned LENGTHEXTRA[29] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0}; /*the base backwards distances (the bits of distance codes appear after length codes and use their own huffman tree)*/ static const unsigned DISTANCEBASE[30] = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; /*the extra bits of backwards distances (added to base)*/ static const unsigned DISTANCEEXTRA[30] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; /*the order in which "code length alphabet code lengths" are stored, out of this the huffman tree of the dynamic huffman tree lengths is generated*/ static const unsigned CLCL_ORDER[NUM_CODE_LENGTH_CODES] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; /* ////////////////////////////////////////////////////////////////////////// */ /* Huffman tree struct, containing multiple representations of the tree */ typedef struct HuffmanTree { unsigned* tree2d; unsigned* tree1d; unsigned* lengths; /*the lengths of the codes of the 1d-tree*/ unsigned maxbitlen; /*maximum number of bits a single code can get*/ unsigned numcodes; /*number of symbols in the alphabet = number of codes*/ } HuffmanTree; /*function used for debug purposes to draw the tree in ascii art with C++*/ /* static void HuffmanTree_draw(HuffmanTree* tree) { std::cout << "tree. length: " << tree->numcodes << " maxbitlen: " << tree->maxbitlen << std::endl; for(size_t i = 0; i != tree->tree1d.size; ++i) { if(tree->lengths.data[i]) std::cout << i << " " << tree->tree1d.data[i] << " " << tree->lengths.data[i] << std::endl; } std::cout << std::endl; }*/ static void HuffmanTree_init(HuffmanTree* tree) { tree->tree2d = 0; tree->tree1d = 0; tree->lengths = 0; } static void HuffmanTree_cleanup(HuffmanTree* tree) { lodepng_free(tree->tree2d); lodepng_free(tree->tree1d); lodepng_free(tree->lengths); } /*the tree representation used by the decoder. return value is error*/ static unsigned HuffmanTree_make2DTree(HuffmanTree* tree) { unsigned nodefilled = 0; /*up to which node it is filled*/ unsigned treepos = 0; /*position in the tree (1 of the numcodes columns)*/ unsigned n, i; tree->tree2d = (unsigned*)lodepng_malloc(tree->numcodes * 2 * sizeof(unsigned)); if(!tree->tree2d) return 83; /*alloc fail*/ /* convert tree1d[] to tree2d[][]. In the 2D array, a value of 32767 means uninited, a value >= numcodes is an address to another bit, a value < numcodes is a code. The 2 rows are the 2 possible bit values (0 or 1), there are as many columns as codes - 1. A good huffman tree has N * 2 - 1 nodes, of which N - 1 are internal nodes. Here, the internal nodes are stored (what their 0 and 1 option point to). There is only memory for such good tree currently, if there are more nodes (due to too long length codes), error 55 will happen */ for(n = 0; n < tree->numcodes * 2; ++n) { tree->tree2d[n] = 32767; /*32767 here means the tree2d isn't filled there yet*/ } for(n = 0; n < tree->numcodes; ++n) /*the codes*/ { for(i = 0; i != tree->lengths[n]; ++i) /*the bits for this code*/ { unsigned char bit = (unsigned char)((tree->tree1d[n] >> (tree->lengths[n] - i - 1)) & 1); /*oversubscribed, see comment in lodepng_error_text*/ if(treepos > 2147483647 || treepos + 2 > tree->numcodes) return 55; if(tree->tree2d[2 * treepos + bit] == 32767) /*not yet filled in*/ { if(i + 1 == tree->lengths[n]) /*last bit*/ { tree->tree2d[2 * treepos + bit] = n; /*put the current code in it*/ treepos = 0; } else { /*put address of the next step in here, first that address has to be found of course (it's just nodefilled + 1)...*/ ++nodefilled; /*addresses encoded with numcodes added to it*/ tree->tree2d[2 * treepos + bit] = nodefilled + tree->numcodes; treepos = nodefilled; } } else treepos = tree->tree2d[2 * treepos + bit] - tree->numcodes; } } for(n = 0; n < tree->numcodes * 2; ++n) { if(tree->tree2d[n] == 32767) tree->tree2d[n] = 0; /*remove possible remaining 32767's*/ } return 0; } /* Second step for the ...makeFromLengths and ...makeFromFrequencies functions. numcodes, lengths and maxbitlen must already be filled in correctly. return value is error. */ static unsigned HuffmanTree_makeFromLengths2(HuffmanTree* tree) { uivector blcount; uivector nextcode; unsigned error = 0; unsigned bits, n; uivector_init(&blcount); uivector_init(&nextcode); tree->tree1d = (unsigned*)lodepng_malloc(tree->numcodes * sizeof(unsigned)); if(!tree->tree1d) error = 83; /*alloc fail*/ if(!uivector_resizev(&blcount, tree->maxbitlen + 1, 0) || !uivector_resizev(&nextcode, tree->maxbitlen + 1, 0)) error = 83; /*alloc fail*/ if(!error) { /*step 1: count number of instances of each code length*/ for(bits = 0; bits != tree->numcodes; ++bits) ++blcount.data[tree->lengths[bits]]; /*step 2: generate the nextcode values*/ for(bits = 1; bits <= tree->maxbitlen; ++bits) { nextcode.data[bits] = (nextcode.data[bits - 1] + blcount.data[bits - 1]) << 1; } /*step 3: generate all the codes*/ for(n = 0; n != tree->numcodes; ++n) { if(tree->lengths[n] != 0) tree->tree1d[n] = nextcode.data[tree->lengths[n]]++; } } uivector_cleanup(&blcount); uivector_cleanup(&nextcode); if(!error) return HuffmanTree_make2DTree(tree); else return error; } /* given the code lengths (as stored in the PNG file), generate the tree as defined by Deflate. maxbitlen is the maximum bits that a code in the tree can have. return value is error. */ static unsigned HuffmanTree_makeFromLengths(HuffmanTree* tree, const unsigned* bitlen, size_t numcodes, unsigned maxbitlen) { unsigned i; tree->lengths = (unsigned*)lodepng_malloc(numcodes * sizeof(unsigned)); if(!tree->lengths) return 83; /*alloc fail*/ for(i = 0; i != numcodes; ++i) tree->lengths[i] = bitlen[i]; tree->numcodes = (unsigned)numcodes; /*number of symbols*/ tree->maxbitlen = maxbitlen; return HuffmanTree_makeFromLengths2(tree); } #ifdef LODEPNG_COMPILE_ENCODER /*BPM: Boundary Package Merge, see "A Fast and Space-Economical Algorithm for Length-Limited Coding", Jyrki Katajainen, Alistair Moffat, Andrew Turpin, 1995.*/ /*chain node for boundary package merge*/ typedef struct BPMNode { int weight; /*the sum of all weights in this chain*/ unsigned index; /*index of this leaf node (called "count" in the paper)*/ struct BPMNode* tail; /*the next nodes in this chain (null if last)*/ int in_use; } BPMNode; /*lists of chains*/ typedef struct BPMLists { /*memory pool*/ unsigned memsize; BPMNode* memory; unsigned numfree; unsigned nextfree; BPMNode** freelist; /*two heads of lookahead chains per list*/ unsigned listsize; BPMNode** chains0; BPMNode** chains1; } BPMLists; /*creates a new chain node with the given parameters, from the memory in the lists */ static BPMNode* bpmnode_create(BPMLists* lists, int weight, unsigned index, BPMNode* tail) { unsigned i; BPMNode* result; /*memory full, so garbage collect*/ if(lists->nextfree >= lists->numfree) { /*mark only those that are in use*/ for(i = 0; i != lists->memsize; ++i) lists->memory[i].in_use = 0; for(i = 0; i != lists->listsize; ++i) { BPMNode* node; for(node = lists->chains0[i]; node != 0; node = node->tail) node->in_use = 1; for(node = lists->chains1[i]; node != 0; node = node->tail) node->in_use = 1; } /*collect those that are free*/ lists->numfree = 0; for(i = 0; i != lists->memsize; ++i) { if(!lists->memory[i].in_use) lists->freelist[lists->numfree++] = &lists->memory[i]; } lists->nextfree = 0; } result = lists->freelist[lists->nextfree++]; result->weight = weight; result->index = index; result->tail = tail; return result; } /*sort the leaves with stable mergesort*/ static void bpmnode_sort(BPMNode* leaves, size_t num) { BPMNode* mem = (BPMNode*)lodepng_malloc(sizeof(*leaves) * num); size_t width, counter = 0; for(width = 1; width < num; width *= 2) { BPMNode* a = (counter & 1) ? mem : leaves; BPMNode* b = (counter & 1) ? leaves : mem; size_t p; for(p = 0; p < num; p += 2 * width) { size_t q = (p + width > num) ? num : (p + width); size_t r = (p + 2 * width > num) ? num : (p + 2 * width); size_t i = p, j = q, k; for(k = p; k < r; k++) { if(i < q && (j >= r || a[i].weight <= a[j].weight)) b[k] = a[i++]; else b[k] = a[j++]; } } counter++; } if(counter & 1) memcpy(leaves, mem, sizeof(*leaves) * num); lodepng_free(mem); } /*Boundary Package Merge step, numpresent is the amount of leaves, and c is the current chain.*/ static void boundaryPM(BPMLists* lists, BPMNode* leaves, size_t numpresent, int c, int num) { unsigned lastindex = lists->chains1[c]->index; if(c == 0) { if(lastindex >= numpresent) return; lists->chains0[c] = lists->chains1[c]; lists->chains1[c] = bpmnode_create(lists, leaves[lastindex].weight, lastindex + 1, 0); } else { /*sum of the weights of the head nodes of the previous lookahead chains.*/ int sum = lists->chains0[c - 1]->weight + lists->chains1[c - 1]->weight; lists->chains0[c] = lists->chains1[c]; if(lastindex < numpresent && sum > leaves[lastindex].weight) { lists->chains1[c] = bpmnode_create(lists, leaves[lastindex].weight, lastindex + 1, lists->chains1[c]->tail); return; } lists->chains1[c] = bpmnode_create(lists, sum, lastindex, lists->chains1[c - 1]); /*in the end we are only interested in the chain of the last list, so no need to recurse if we're at the last one (this gives measurable speedup)*/ if(num + 1 < (int)(2 * numpresent - 2)) { boundaryPM(lists, leaves, numpresent, c - 1, num); boundaryPM(lists, leaves, numpresent, c - 1, num); } } } unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies, size_t numcodes, unsigned maxbitlen) { unsigned error = 0; unsigned i; size_t numpresent = 0; /*number of symbols with non-zero frequency*/ BPMNode* leaves; /*the symbols, only those with > 0 frequency*/ if(numcodes == 0) return 80; /*error: a tree of 0 symbols is not supposed to be made*/ if((1u << maxbitlen) < numcodes) return 80; /*error: represent all symbols*/ leaves = (BPMNode*)lodepng_malloc(numcodes * sizeof(*leaves)); if(!leaves) return 83; /*alloc fail*/ for(i = 0; i != numcodes; ++i) { if(frequencies[i] > 0) { leaves[numpresent].weight = (int)frequencies[i]; leaves[numpresent].index = i; ++numpresent; } } for(i = 0; i != numcodes; ++i) lengths[i] = 0; /*ensure at least two present symbols. There should be at least one symbol according to RFC 1951 section 3.2.7. Some decoders incorrectly require two. To make these work as well ensure there are at least two symbols. The Package-Merge code below also doesn't work correctly if there's only one symbol, it'd give it the theoritical 0 bits but in practice zlib wants 1 bit*/ if(numpresent == 0) { lengths[0] = lengths[1] = 1; /*note that for RFC 1951 section 3.2.7, only lengths[0] = 1 is needed*/ } else if(numpresent == 1) { lengths[leaves[0].index] = 1; lengths[leaves[0].index == 0 ? 1 : 0] = 1; } else { BPMLists lists; BPMNode* node; bpmnode_sort(leaves, numpresent); lists.listsize = maxbitlen; lists.memsize = 2 * maxbitlen * (maxbitlen + 1); lists.nextfree = 0; lists.numfree = lists.memsize; lists.memory = (BPMNode*)lodepng_malloc(lists.memsize * sizeof(*lists.memory)); lists.freelist = (BPMNode**)lodepng_malloc(lists.memsize * sizeof(BPMNode*)); lists.chains0 = (BPMNode**)lodepng_malloc(lists.listsize * sizeof(BPMNode*)); lists.chains1 = (BPMNode**)lodepng_malloc(lists.listsize * sizeof(BPMNode*)); if(!lists.memory || !lists.freelist || !lists.chains0 || !lists.chains1) error = 83; /*alloc fail*/ if(!error) { for(i = 0; i != lists.memsize; ++i) lists.freelist[i] = &lists.memory[i]; bpmnode_create(&lists, leaves[0].weight, 1, 0); bpmnode_create(&lists, leaves[1].weight, 2, 0); for(i = 0; i != lists.listsize; ++i) { lists.chains0[i] = &lists.memory[0]; lists.chains1[i] = &lists.memory[1]; } /*each boundaryPM call adds one chain to the last list, and we need 2 * numpresent - 2 chains.*/ for(i = 2; i != 2 * numpresent - 2; ++i) boundaryPM(&lists, leaves, numpresent, (int)maxbitlen - 1, (int)i); for(node = lists.chains1[maxbitlen - 1]; node; node = node->tail) { for(i = 0; i != node->index; ++i) ++lengths[leaves[i].index]; } } lodepng_free(lists.memory); lodepng_free(lists.freelist); lodepng_free(lists.chains0); lodepng_free(lists.chains1); } lodepng_free(leaves); return error; } /*Create the Huffman tree given the symbol frequencies*/ static unsigned HuffmanTree_makeFromFrequencies(HuffmanTree* tree, const unsigned* frequencies, size_t mincodes, size_t numcodes, unsigned maxbitlen) { unsigned error = 0; while(!frequencies[numcodes - 1] && numcodes > mincodes) --numcodes; /*trim zeroes*/ tree->maxbitlen = maxbitlen; tree->numcodes = (unsigned)numcodes; /*number of symbols*/ tree->lengths = (unsigned*)lodepng_realloc(tree->lengths, numcodes * sizeof(unsigned)); if(!tree->lengths) return 83; /*alloc fail*/ /*initialize all lengths to 0*/ memset(tree->lengths, 0, numcodes * sizeof(unsigned)); error = lodepng_huffman_code_lengths(tree->lengths, frequencies, numcodes, maxbitlen); if(!error) error = HuffmanTree_makeFromLengths2(tree); return error; } static unsigned HuffmanTree_getCode(const HuffmanTree* tree, unsigned index) { return tree->tree1d[index]; } static unsigned HuffmanTree_getLength(const HuffmanTree* tree, unsigned index) { return tree->lengths[index]; } #endif /*LODEPNG_COMPILE_ENCODER*/ /*get the literal and length code tree of a deflated block with fixed tree, as per the deflate specification*/ static unsigned generateFixedLitLenTree(HuffmanTree* tree) { unsigned i, error = 0; unsigned* bitlen = (unsigned*)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned)); if(!bitlen) return 83; /*alloc fail*/ /*288 possible codes: 0-255=literals, 256=endcode, 257-285=lengthcodes, 286-287=unused*/ for(i = 0; i <= 143; ++i) bitlen[i] = 8; for(i = 144; i <= 255; ++i) bitlen[i] = 9; for(i = 256; i <= 279; ++i) bitlen[i] = 7; for(i = 280; i <= 287; ++i) bitlen[i] = 8; error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DEFLATE_CODE_SYMBOLS, 15); lodepng_free(bitlen); return error; } /*get the distance code tree of a deflated block with fixed tree, as specified in the deflate specification*/ static unsigned generateFixedDistanceTree(HuffmanTree* tree) { unsigned i, error = 0; unsigned* bitlen = (unsigned*)lodepng_malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned)); if(!bitlen) return 83; /*alloc fail*/ /*there are 32 distance codes, but 30-31 are unused*/ for(i = 0; i != NUM_DISTANCE_SYMBOLS; ++i) bitlen[i] = 5; error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DISTANCE_SYMBOLS, 15); lodepng_free(bitlen); return error; } #ifdef LODEPNG_COMPILE_DECODER /* returns the code, or (unsigned)(-1) if error happened inbitlength is the length of the complete buffer, in bits (so its byte length times 8) */ static unsigned huffmanDecodeSymbol(const unsigned char* in, size_t* bp, const HuffmanTree* codetree, size_t inbitlength) { unsigned treepos = 0, ct; for(;;) { if(*bp >= inbitlength) return (unsigned)(-1); /*error: end of input memory reached without endcode*/ /* decode the symbol from the tree. The "readBitFromStream" code is inlined in the expression below because this is the biggest bottleneck while decoding */ ct = codetree->tree2d[(treepos << 1) + READBIT(*bp, in)]; ++(*bp); if(ct < codetree->numcodes) return ct; /*the symbol is decoded, return it*/ else treepos = ct - codetree->numcodes; /*symbol not yet decoded, instead move tree position*/ if(treepos >= codetree->numcodes) return (unsigned)(-1); /*error: it appeared outside the codetree*/ } } #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_DECODER /* ////////////////////////////////////////////////////////////////////////// */ /* / Inflator (Decompressor) / */ /* ////////////////////////////////////////////////////////////////////////// */ /*get the tree of a deflated block with fixed tree, as specified in the deflate specification*/ static void getTreeInflateFixed(HuffmanTree* tree_ll, HuffmanTree* tree_d) { /*TODO: check for out of memory errors*/ generateFixedLitLenTree(tree_ll); generateFixedDistanceTree(tree_d); } /*get the tree of a deflated block with dynamic tree, the tree itself is also Huffman compressed with a known tree*/ static unsigned getTreeInflateDynamic(HuffmanTree* tree_ll, HuffmanTree* tree_d, const unsigned char* in, size_t* bp, size_t inlength) { /*make sure that length values that aren't filled in will be 0, or a wrong tree will be generated*/ unsigned error = 0; unsigned n, HLIT, HDIST, HCLEN, i; size_t inbitlength = inlength * 8; /*see comments in deflateDynamic for explanation of the context and these variables, it is analogous*/ unsigned* bitlen_ll = 0; /*lit,len code lengths*/ unsigned* bitlen_d = 0; /*dist code lengths*/ /*code length code lengths ("clcl"), the bit lengths of the huffman tree used to compress bitlen_ll and bitlen_d*/ unsigned* bitlen_cl = 0; HuffmanTree tree_cl; /*the code tree for code length codes (the huffman tree for compressed huffman trees)*/ if((*bp) + 14 > (inlength << 3)) return 49; /*error: the bit pointer is or will go past the memory*/ /*number of literal/length codes + 257. Unlike the spec, the value 257 is added to it here already*/ HLIT = readBitsFromStream(bp, in, 5) + 257; /*number of distance codes. Unlike the spec, the value 1 is added to it here already*/ HDIST = readBitsFromStream(bp, in, 5) + 1; /*number of code length codes. Unlike the spec, the value 4 is added to it here already*/ HCLEN = readBitsFromStream(bp, in, 4) + 4; if((*bp) + HCLEN * 3 > (inlength << 3)) return 50; /*error: the bit pointer is or will go past the memory*/ HuffmanTree_init(&tree_cl); while(!error) { /*read the code length codes out of 3 * (amount of code length codes) bits*/ bitlen_cl = (unsigned*)lodepng_malloc(NUM_CODE_LENGTH_CODES * sizeof(unsigned)); if(!bitlen_cl) ERROR_BREAK(83 /*alloc fail*/); for(i = 0; i != NUM_CODE_LENGTH_CODES; ++i) { if(i < HCLEN) bitlen_cl[CLCL_ORDER[i]] = readBitsFromStream(bp, in, 3); else bitlen_cl[CLCL_ORDER[i]] = 0; /*if not, it must stay 0*/ } error = HuffmanTree_makeFromLengths(&tree_cl, bitlen_cl, NUM_CODE_LENGTH_CODES, 7); if(error) break; /*now we can use this tree to read the lengths for the tree that this function will return*/ bitlen_ll = (unsigned*)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned)); bitlen_d = (unsigned*)lodepng_malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned)); if(!bitlen_ll || !bitlen_d) ERROR_BREAK(83 /*alloc fail*/); for(i = 0; i != NUM_DEFLATE_CODE_SYMBOLS; ++i) bitlen_ll[i] = 0; for(i = 0; i != NUM_DISTANCE_SYMBOLS; ++i) bitlen_d[i] = 0; /*i is the current symbol we're reading in the part that contains the code lengths of lit/len and dist codes*/ i = 0; while(i < HLIT + HDIST) { unsigned code = huffmanDecodeSymbol(in, bp, &tree_cl, inbitlength); if(code <= 15) /*a length code*/ { if(i < HLIT) bitlen_ll[i] = code; else bitlen_d[i - HLIT] = code; ++i; } else if(code == 16) /*repeat previous*/ { unsigned replength = 3; /*read in the 2 bits that indicate repeat length (3-6)*/ unsigned value; /*set value to the previous code*/ if(i == 0) ERROR_BREAK(54); /*can't repeat previous if i is 0*/ if((*bp + 2) > inbitlength) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ replength += readBitsFromStream(bp, in, 2); if(i < HLIT + 1) value = bitlen_ll[i - 1]; else value = bitlen_d[i - HLIT - 1]; /*repeat this value in the next lengths*/ for(n = 0; n < replength; ++n) { if(i >= HLIT + HDIST) ERROR_BREAK(13); /*error: i is larger than the amount of codes*/ if(i < HLIT) bitlen_ll[i] = value; else bitlen_d[i - HLIT] = value; ++i; } } else if(code == 17) /*repeat "0" 3-10 times*/ { unsigned replength = 3; /*read in the bits that indicate repeat length*/ if((*bp + 3) > inbitlength) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ replength += readBitsFromStream(bp, in, 3); /*repeat this value in the next lengths*/ for(n = 0; n < replength; ++n) { if(i >= HLIT + HDIST) ERROR_BREAK(14); /*error: i is larger than the amount of codes*/ if(i < HLIT) bitlen_ll[i] = 0; else bitlen_d[i - HLIT] = 0; ++i; } } else if(code == 18) /*repeat "0" 11-138 times*/ { unsigned replength = 11; /*read in the bits that indicate repeat length*/ if((*bp + 7) > inbitlength) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ replength += readBitsFromStream(bp, in, 7); /*repeat this value in the next lengths*/ for(n = 0; n < replength; ++n) { if(i >= HLIT + HDIST) ERROR_BREAK(15); /*error: i is larger than the amount of codes*/ if(i < HLIT) bitlen_ll[i] = 0; else bitlen_d[i - HLIT] = 0; ++i; } } else /*if(code == (unsigned)(-1))*/ /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ { if(code == (unsigned)(-1)) { /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol (10=no endcode, 11=wrong jump outside of tree)*/ error = (*bp) > inbitlength ? 10 : 11; } else error = 16; /*unexisting code, this can never happen*/ break; } } if(error) break; if(bitlen_ll[256] == 0) ERROR_BREAK(64); /*the length of the end code 256 must be larger than 0*/ /*now we've finally got HLIT and HDIST, so generate the code trees, and the function is done*/ error = HuffmanTree_makeFromLengths(tree_ll, bitlen_ll, NUM_DEFLATE_CODE_SYMBOLS, 15); if(error) break; error = HuffmanTree_makeFromLengths(tree_d, bitlen_d, NUM_DISTANCE_SYMBOLS, 15); break; /*end of error-while*/ } lodepng_free(bitlen_cl); lodepng_free(bitlen_ll); lodepng_free(bitlen_d); HuffmanTree_cleanup(&tree_cl); return error; } /*inflate a block with dynamic of fixed Huffman tree*/ static unsigned inflateHuffmanBlock(ucvector* out, const unsigned char* in, size_t* bp, size_t* pos, size_t inlength, unsigned btype) { unsigned error = 0; HuffmanTree tree_ll; /*the huffman tree for literal and length codes*/ HuffmanTree tree_d; /*the huffman tree for distance codes*/ size_t inbitlength = inlength * 8; HuffmanTree_init(&tree_ll); HuffmanTree_init(&tree_d); if(btype == 1) getTreeInflateFixed(&tree_ll, &tree_d); else if(btype == 2) error = getTreeInflateDynamic(&tree_ll, &tree_d, in, bp, inlength); while(!error) /*decode all symbols until end reached, breaks at end code*/ { /*code_ll is literal, length or end code*/ unsigned code_ll = huffmanDecodeSymbol(in, bp, &tree_ll, inbitlength); if(code_ll <= 255) /*literal symbol*/ { /*ucvector_push_back would do the same, but for some reason the two lines below run 10% faster*/ if(!ucvector_resize(out, (*pos) + 1)) ERROR_BREAK(83 /*alloc fail*/); out->data[*pos] = (unsigned char)code_ll; ++(*pos); } else if(code_ll >= FIRST_LENGTH_CODE_INDEX && code_ll <= LAST_LENGTH_CODE_INDEX) /*length code*/ { unsigned code_d, distance; unsigned numextrabits_l, numextrabits_d; /*extra bits for length and distance*/ size_t start, forward, backward, length; /*part 1: get length base*/ length = LENGTHBASE[code_ll - FIRST_LENGTH_CODE_INDEX]; /*part 2: get extra bits and add the value of that to length*/ numextrabits_l = LENGTHEXTRA[code_ll - FIRST_LENGTH_CODE_INDEX]; if((*bp + numextrabits_l) > inbitlength) ERROR_BREAK(51); /*error, bit pointer will jump past memory*/ length += readBitsFromStream(bp, in, numextrabits_l); /*part 3: get distance code*/ code_d = huffmanDecodeSymbol(in, bp, &tree_d, inbitlength); if(code_d > 29) { if(code_ll == (unsigned)(-1)) /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ { /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol (10=no endcode, 11=wrong jump outside of tree)*/ error = (*bp) > inlength * 8 ? 10 : 11; } else error = 18; /*error: invalid distance code (30-31 are never used)*/ break; } distance = DISTANCEBASE[code_d]; /*part 4: get extra bits from distance*/ numextrabits_d = DISTANCEEXTRA[code_d]; if((*bp + numextrabits_d) > inbitlength) ERROR_BREAK(51); /*error, bit pointer will jump past memory*/ distance += readBitsFromStream(bp, in, numextrabits_d); /*part 5: fill in all the out[n] values based on the length and dist*/ start = (*pos); if(distance > start) ERROR_BREAK(52); /*too long backward distance*/ backward = start - distance; if(!ucvector_resize(out, (*pos) + length)) ERROR_BREAK(83 /*alloc fail*/); if (distance < length) { for(forward = 0; forward < length; ++forward) { out->data[(*pos)++] = out->data[backward++]; } } else { memcpy(out->data + *pos, out->data + backward, length); *pos += length; } } else if(code_ll == 256) { break; /*end code, break the loop*/ } else /*if(code == (unsigned)(-1))*/ /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ { /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol (10=no endcode, 11=wrong jump outside of tree)*/ error = ((*bp) > inlength * 8) ? 10 : 11; break; } } HuffmanTree_cleanup(&tree_ll); HuffmanTree_cleanup(&tree_d); return error; } static unsigned inflateNoCompression(ucvector* out, const unsigned char* in, size_t* bp, size_t* pos, size_t inlength) { size_t p; unsigned LEN, NLEN, n, error = 0; /*go to first boundary of byte*/ while(((*bp) & 0x7) != 0) ++(*bp); p = (*bp) / 8; /*byte position*/ /*read LEN (2 bytes) and NLEN (2 bytes)*/ if(p + 4 >= inlength) return 52; /*error, bit pointer will jump past memory*/ LEN = in[p] + 256u * in[p + 1]; p += 2; NLEN = in[p] + 256u * in[p + 1]; p += 2; /*check if 16-bit NLEN is really the one's complement of LEN*/ if(LEN + NLEN != 65535) return 21; /*error: NLEN is not one's complement of LEN*/ if(!ucvector_resize(out, (*pos) + LEN)) return 83; /*alloc fail*/ /*read the literal data: LEN bytes are now stored in the out buffer*/ if(p + LEN > inlength) return 23; /*error: reading outside of in buffer*/ for(n = 0; n < LEN; ++n) out->data[(*pos)++] = in[p++]; (*bp) = p * 8; return error; } static unsigned lodepng_inflatev(ucvector* out, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings) { /*bit pointer in the "in" data, current byte is bp >> 3, current bit is bp & 0x7 (from lsb to msb of the byte)*/ size_t bp = 0; unsigned BFINAL = 0; size_t pos = 0; /*byte position in the out buffer*/ unsigned error = 0; (void)settings; while(!BFINAL) { unsigned BTYPE; if(bp + 2 >= insize * 8) return 52; /*error, bit pointer will jump past memory*/ BFINAL = readBitFromStream(&bp, in); BTYPE = 1u * readBitFromStream(&bp, in); BTYPE += 2u * readBitFromStream(&bp, in); if(BTYPE == 3) return 20; /*error: invalid BTYPE*/ else if(BTYPE == 0) error = inflateNoCompression(out, in, &bp, &pos, insize); /*no compression*/ else error = inflateHuffmanBlock(out, in, &bp, &pos, insize, BTYPE); /*compression, BTYPE 01 or 10*/ if(error) return error; } return error; } unsigned lodepng_inflate(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings) { unsigned error; ucvector v; ucvector_init_buffer(&v, *out, *outsize); error = lodepng_inflatev(&v, in, insize, settings); *out = v.data; *outsize = v.size; return error; } static unsigned inflate(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings) { if(settings->custom_inflate) { return settings->custom_inflate(out, outsize, in, insize, settings); } else { return lodepng_inflate(out, outsize, in, insize, settings); } } #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER /* ////////////////////////////////////////////////////////////////////////// */ /* / Deflator (Compressor) / */ /* ////////////////////////////////////////////////////////////////////////// */ static const size_t MAX_SUPPORTED_DEFLATE_LENGTH = 258; /*bitlen is the size in bits of the code*/ static void addHuffmanSymbol(size_t* bp, ucvector* compressed, unsigned code, unsigned bitlen) { addBitsToStreamReversed(bp, compressed, code, bitlen); } /*search the index in the array, that has the largest value smaller than or equal to the given value, given array must be sorted (if no value is smaller, it returns the size of the given array)*/ static size_t searchCodeIndex(const unsigned* array, size_t array_size, size_t value) { /*binary search (only small gain over linear). TODO: use CPU log2 instruction for getting symbols instead*/ size_t left = 1; size_t right = array_size - 1; while(left <= right) { size_t mid = (left + right) >> 1; if (array[mid] >= value) right = mid - 1; else left = mid + 1; } if(left >= array_size || array[left] > value) left--; return left; } static void addLengthDistance(uivector* values, size_t length, size_t distance) { /*values in encoded vector are those used by deflate: 0-255: literal bytes 256: end 257-285: length/distance pair (length code, followed by extra length bits, distance code, extra distance bits) 286-287: invalid*/ unsigned length_code = (unsigned)searchCodeIndex(LENGTHBASE, 29, length); unsigned extra_length = (unsigned)(length - LENGTHBASE[length_code]); unsigned dist_code = (unsigned)searchCodeIndex(DISTANCEBASE, 30, distance); unsigned extra_distance = (unsigned)(distance - DISTANCEBASE[dist_code]); uivector_push_back(values, length_code + FIRST_LENGTH_CODE_INDEX); uivector_push_back(values, extra_length); uivector_push_back(values, dist_code); uivector_push_back(values, extra_distance); } /*3 bytes of data get encoded into two bytes. The hash cannot use more than 3 bytes as input because 3 is the minimum match length for deflate*/ static const unsigned HASH_NUM_VALUES = 65536; static const unsigned HASH_BIT_MASK = 65535; /*HASH_NUM_VALUES - 1, but C90 does not like that as initializer*/ typedef struct Hash { int* head; /*hash value to head circular pos - can be outdated if went around window*/ /*circular pos to prev circular pos*/ unsigned short* chain; int* val; /*circular pos to hash value*/ /*TODO: do this not only for zeros but for any repeated byte. However for PNG it's always going to be the zeros that dominate, so not important for PNG*/ int* headz; /*similar to head, but for chainz*/ unsigned short* chainz; /*those with same amount of zeros*/ unsigned short* zeros; /*length of zeros streak, used as a second hash chain*/ } Hash; static unsigned hash_init(Hash* hash, unsigned windowsize) { unsigned i; hash->head = (int*)lodepng_malloc(sizeof(int) * HASH_NUM_VALUES); hash->val = (int*)lodepng_malloc(sizeof(int) * windowsize); hash->chain = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); hash->zeros = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); hash->headz = (int*)lodepng_malloc(sizeof(int) * (MAX_SUPPORTED_DEFLATE_LENGTH + 1)); hash->chainz = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); if(!hash->head || !hash->chain || !hash->val || !hash->headz|| !hash->chainz || !hash->zeros) { return 83; /*alloc fail*/ } /*initialize hash table*/ for(i = 0; i != HASH_NUM_VALUES; ++i) hash->head[i] = -1; for(i = 0; i != windowsize; ++i) hash->val[i] = -1; for(i = 0; i != windowsize; ++i) hash->chain[i] = i; /*same value as index indicates uninitialized*/ for(i = 0; i <= MAX_SUPPORTED_DEFLATE_LENGTH; ++i) hash->headz[i] = -1; for(i = 0; i != windowsize; ++i) hash->chainz[i] = i; /*same value as index indicates uninitialized*/ return 0; } static void hash_cleanup(Hash* hash) { lodepng_free(hash->head); lodepng_free(hash->val); lodepng_free(hash->chain); lodepng_free(hash->zeros); lodepng_free(hash->headz); lodepng_free(hash->chainz); } static unsigned getHash(const unsigned char* data, size_t size, size_t pos) { unsigned result = 0; if(pos + 2 < size) { /*A simple shift and xor hash is used. Since the data of PNGs is dominated by zeroes due to the filters, a better hash does not have a significant effect on speed in traversing the chain, and causes more time spend on calculating the hash.*/ result ^= (unsigned)(data[pos + 0] << 0u); result ^= (unsigned)(data[pos + 1] << 4u); result ^= (unsigned)(data[pos + 2] << 8u); } else { size_t amount, i; if(pos >= size) return 0; amount = size - pos; for(i = 0; i != amount; ++i) result ^= (unsigned)(data[pos + i] << (i * 8u)); } return result & HASH_BIT_MASK; } static unsigned countZeros(const unsigned char* data, size_t size, size_t pos) { const unsigned char* start = data + pos; const unsigned char* end = start + MAX_SUPPORTED_DEFLATE_LENGTH; if(end > data + size) end = data + size; data = start; while(data != end && *data == 0) ++data; /*subtracting two addresses returned as 32-bit number (max value is MAX_SUPPORTED_DEFLATE_LENGTH)*/ return (unsigned)(data - start); } /*wpos = pos & (windowsize - 1)*/ static void updateHashChain(Hash* hash, size_t wpos, unsigned hashval, unsigned short numzeros) { hash->val[wpos] = (int)hashval; if(hash->head[hashval] != -1) hash->chain[wpos] = hash->head[hashval]; hash->head[hashval] = wpos; hash->zeros[wpos] = numzeros; if(hash->headz[numzeros] != -1) hash->chainz[wpos] = hash->headz[numzeros]; hash->headz[numzeros] = wpos; } /* LZ77-encode the data. Return value is error code. The input are raw bytes, the output is in the form of unsigned integers with codes representing for example literal bytes, or length/distance pairs. It uses a hash table technique to let it encode faster. When doing LZ77 encoding, a sliding window (of windowsize) is used, and all past bytes in that window can be used as the "dictionary". A brute force search through all possible distances would be slow, and this hash technique is one out of several ways to speed this up. */ static unsigned encodeLZ77(uivector* out, Hash* hash, const unsigned char* in, size_t inpos, size_t insize, unsigned windowsize, unsigned minmatch, unsigned nicematch, unsigned lazymatching) { size_t pos; unsigned i, error = 0; /*for large window lengths, assume the user wants no compression loss. Otherwise, max hash chain length speedup.*/ unsigned maxchainlength = windowsize >= 8192 ? windowsize : windowsize / 8; unsigned maxlazymatch = windowsize >= 8192 ? MAX_SUPPORTED_DEFLATE_LENGTH : 64; unsigned usezeros = 1; /*not sure if setting it to false for windowsize < 8192 is better or worse*/ unsigned numzeros = 0; unsigned offset; /*the offset represents the distance in LZ77 terminology*/ unsigned length; unsigned lazy = 0; unsigned lazylength = 0, lazyoffset = 0; unsigned hashval; unsigned current_offset, current_length; unsigned prev_offset; const unsigned char *lastptr, *foreptr, *backptr; unsigned hashpos; if(windowsize == 0 || windowsize > 32768) return 60; /*error: windowsize smaller/larger than allowed*/ if((windowsize & (windowsize - 1)) != 0) return 90; /*error: must be power of two*/ if(nicematch > MAX_SUPPORTED_DEFLATE_LENGTH) nicematch = MAX_SUPPORTED_DEFLATE_LENGTH; for(pos = inpos; pos < insize; ++pos) { size_t wpos = pos & (windowsize - 1); /*position for in 'circular' hash buffers*/ unsigned chainlength = 0; hashval = getHash(in, insize, pos); if(usezeros && hashval == 0) { if(numzeros == 0) numzeros = countZeros(in, insize, pos); else if(pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros; } else { numzeros = 0; } updateHashChain(hash, wpos, hashval, numzeros); /*the length and offset found for the current position*/ length = 0; offset = 0; hashpos = hash->chain[wpos]; lastptr = &in[insize < pos + MAX_SUPPORTED_DEFLATE_LENGTH ? insize : pos + MAX_SUPPORTED_DEFLATE_LENGTH]; /*search for the longest string*/ prev_offset = 0; for(;;) { if(chainlength++ >= maxchainlength) break; current_offset = hashpos <= wpos ? wpos - hashpos : wpos - hashpos + windowsize; if(current_offset < prev_offset) break; /*stop when went completely around the circular buffer*/ prev_offset = current_offset; if(current_offset > 0) { /*test the next characters*/ foreptr = &in[pos]; backptr = &in[pos - current_offset]; /*common case in PNGs is lots of zeros. Quickly skip over them as a speedup*/ if(numzeros >= 3) { unsigned skip = hash->zeros[hashpos]; if(skip > numzeros) skip = numzeros; backptr += skip; foreptr += skip; } while(foreptr != lastptr && *backptr == *foreptr) /*maximum supported length by deflate is max length*/ { ++backptr; ++foreptr; } current_length = (unsigned)(foreptr - &in[pos]); if(current_length > length) { length = current_length; /*the longest length*/ offset = current_offset; /*the offset that is related to this longest length*/ /*jump out once a length of max length is found (speed gain). This also jumps out if length is MAX_SUPPORTED_DEFLATE_LENGTH*/ if(current_length >= nicematch) break; } } if(hashpos == hash->chain[hashpos]) break; if(numzeros >= 3 && length > numzeros) { hashpos = hash->chainz[hashpos]; if(hash->zeros[hashpos] != numzeros) break; } else { hashpos = hash->chain[hashpos]; /*outdated hash value, happens if particular value was not encountered in whole last window*/ if(hash->val[hashpos] != (int)hashval) break; } } if(lazymatching) { if(!lazy && length >= 3 && length <= maxlazymatch && length < MAX_SUPPORTED_DEFLATE_LENGTH) { lazy = 1; lazylength = length; lazyoffset = offset; continue; /*try the next byte*/ } if(lazy) { lazy = 0; if(pos == 0) ERROR_BREAK(81); if(length > lazylength + 1) { /*push the previous character as literal*/ if(!uivector_push_back(out, in[pos - 1])) ERROR_BREAK(83 /*alloc fail*/); } else { length = lazylength; offset = lazyoffset; hash->head[hashval] = -1; /*the same hashchain update will be done, this ensures no wrong alteration*/ hash->headz[numzeros] = -1; /*idem*/ --pos; } } } if(length >= 3 && offset > windowsize) ERROR_BREAK(86 /*too big (or overflown negative) offset*/); /*encode it as length/distance pair or literal value*/ if(length < 3) /*only lengths of 3 or higher are supported as length/distance pair*/ { if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/); } else if(length < minmatch || (length == 3 && offset > 4096)) { /*compensate for the fact that longer offsets have more extra bits, a length of only 3 may be not worth it then*/ if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/); } else { addLengthDistance(out, length, offset); for(i = 1; i < length; ++i) { ++pos; wpos = pos & (windowsize - 1); hashval = getHash(in, insize, pos); if(usezeros && hashval == 0) { if(numzeros == 0) numzeros = countZeros(in, insize, pos); else if(pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros; } else { numzeros = 0; } updateHashChain(hash, wpos, hashval, numzeros); } } } /*end of the loop through each character of input*/ return error; } /* /////////////////////////////////////////////////////////////////////////// */ static unsigned deflateNoCompression(ucvector* out, const unsigned char* data, size_t datasize) { /*non compressed deflate block data: 1 bit BFINAL,2 bits BTYPE,(5 bits): it jumps to start of next byte, 2 bytes LEN, 2 bytes NLEN, LEN bytes literal DATA*/ size_t i, j, numdeflateblocks = (datasize + 65534) / 65535; unsigned datapos = 0; for(i = 0; i != numdeflateblocks; ++i) { unsigned BFINAL, BTYPE, LEN, NLEN; unsigned char firstbyte; BFINAL = (i == numdeflateblocks - 1); BTYPE = 0; firstbyte = (unsigned char)(BFINAL + ((BTYPE & 1) << 1) + ((BTYPE & 2) << 1)); ucvector_push_back(out, firstbyte); LEN = 65535; if(datasize - datapos < 65535) LEN = (unsigned)datasize - datapos; NLEN = 65535 - LEN; ucvector_push_back(out, (unsigned char)(LEN & 255)); ucvector_push_back(out, (unsigned char)(LEN >> 8)); ucvector_push_back(out, (unsigned char)(NLEN & 255)); ucvector_push_back(out, (unsigned char)(NLEN >> 8)); /*Decompressed data*/ for(j = 0; j < 65535 && datapos < datasize; ++j) { ucvector_push_back(out, data[datapos++]); } } return 0; } /* write the lz77-encoded data, which has lit, len and dist codes, to compressed stream using huffman trees. tree_ll: the tree for lit and len codes. tree_d: the tree for distance codes. */ static void writeLZ77data(size_t* bp, ucvector* out, const uivector* lz77_encoded, const HuffmanTree* tree_ll, const HuffmanTree* tree_d) { size_t i = 0; for(i = 0; i != lz77_encoded->size; ++i) { unsigned val = lz77_encoded->data[i]; addHuffmanSymbol(bp, out, HuffmanTree_getCode(tree_ll, val), HuffmanTree_getLength(tree_ll, val)); if(val > 256) /*for a length code, 3 more things have to be added*/ { unsigned length_index = val - FIRST_LENGTH_CODE_INDEX; unsigned n_length_extra_bits = LENGTHEXTRA[length_index]; unsigned length_extra_bits = lz77_encoded->data[++i]; unsigned distance_code = lz77_encoded->data[++i]; unsigned distance_index = distance_code; unsigned n_distance_extra_bits = DISTANCEEXTRA[distance_index]; unsigned distance_extra_bits = lz77_encoded->data[++i]; addBitsToStream(bp, out, length_extra_bits, n_length_extra_bits); addHuffmanSymbol(bp, out, HuffmanTree_getCode(tree_d, distance_code), HuffmanTree_getLength(tree_d, distance_code)); addBitsToStream(bp, out, distance_extra_bits, n_distance_extra_bits); } } } /*Deflate for a block of type "dynamic", that is, with freely, optimally, created huffman trees*/ static unsigned deflateDynamic(ucvector* out, size_t* bp, Hash* hash, const unsigned char* data, size_t datapos, size_t dataend, const LodePNGCompressSettings* settings, unsigned final) { unsigned error = 0; /* A block is compressed as follows: The PNG data is lz77 encoded, resulting in literal bytes and length/distance pairs. This is then huffman compressed with two huffman trees. One huffman tree is used for the lit and len values ("ll"), another huffman tree is used for the dist values ("d"). These two trees are stored using their code lengths, and to compress even more these code lengths are also run-length encoded and huffman compressed. This gives a huffman tree of code lengths "cl". The code lenghts used to describe this third tree are the code length code lengths ("clcl"). */ /*The lz77 encoded data, represented with integers since there will also be length and distance codes in it*/ uivector lz77_encoded; HuffmanTree tree_ll; /*tree for lit,len values*/ HuffmanTree tree_d; /*tree for distance codes*/ HuffmanTree tree_cl; /*tree for encoding the code lengths representing tree_ll and tree_d*/ uivector frequencies_ll; /*frequency of lit,len codes*/ uivector frequencies_d; /*frequency of dist codes*/ uivector frequencies_cl; /*frequency of code length codes*/ uivector bitlen_lld; /*lit,len,dist code lenghts (int bits), literally (without repeat codes).*/ uivector bitlen_lld_e; /*bitlen_lld encoded with repeat codes (this is a rudemtary run length compression)*/ /*bitlen_cl is the code length code lengths ("clcl"). The bit lengths of codes to represent tree_cl (these are written as is in the file, it would be crazy to compress these using yet another huffman tree that needs to be represented by yet another set of code lengths)*/ uivector bitlen_cl; size_t datasize = dataend - datapos; /* Due to the huffman compression of huffman tree representations ("two levels"), there are some anologies: bitlen_lld is to tree_cl what data is to tree_ll and tree_d. bitlen_lld_e is to bitlen_lld what lz77_encoded is to data. bitlen_cl is to bitlen_lld_e what bitlen_lld is to lz77_encoded. */ unsigned BFINAL = final; size_t numcodes_ll, numcodes_d, i; unsigned HLIT, HDIST, HCLEN; uivector_init(&lz77_encoded); HuffmanTree_init(&tree_ll); HuffmanTree_init(&tree_d); HuffmanTree_init(&tree_cl); uivector_init(&frequencies_ll); uivector_init(&frequencies_d); uivector_init(&frequencies_cl); uivector_init(&bitlen_lld); uivector_init(&bitlen_lld_e); uivector_init(&bitlen_cl); /*This while loop never loops due to a break at the end, it is here to allow breaking out of it to the cleanup phase on error conditions.*/ while(!error) { if(settings->use_lz77) { error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->windowsize, settings->minmatch, settings->nicematch, settings->lazymatching); if(error) break; } else { if(!uivector_resize(&lz77_encoded, datasize)) ERROR_BREAK(83 /*alloc fail*/); for(i = datapos; i < dataend; ++i) lz77_encoded.data[i - datapos] = data[i]; /*no LZ77, but still will be Huffman compressed*/ } if(!uivector_resizev(&frequencies_ll, 286, 0)) ERROR_BREAK(83 /*alloc fail*/); if(!uivector_resizev(&frequencies_d, 30, 0)) ERROR_BREAK(83 /*alloc fail*/); /*Count the frequencies of lit, len and dist codes*/ for(i = 0; i != lz77_encoded.size; ++i) { unsigned symbol = lz77_encoded.data[i]; ++frequencies_ll.data[symbol]; if(symbol > 256) { unsigned dist = lz77_encoded.data[i + 2]; ++frequencies_d.data[dist]; i += 3; } } frequencies_ll.data[256] = 1; /*there will be exactly 1 end code, at the end of the block*/ /*Make both huffman trees, one for the lit and len codes, one for the dist codes*/ error = HuffmanTree_makeFromFrequencies(&tree_ll, frequencies_ll.data, 257, frequencies_ll.size, 15); if(error) break; /*2, not 1, is chosen for mincodes: some buggy PNG decoders require at least 2 symbols in the dist tree*/ error = HuffmanTree_makeFromFrequencies(&tree_d, frequencies_d.data, 2, frequencies_d.size, 15); if(error) break; numcodes_ll = tree_ll.numcodes; if(numcodes_ll > 286) numcodes_ll = 286; numcodes_d = tree_d.numcodes; if(numcodes_d > 30) numcodes_d = 30; /*store the code lengths of both generated trees in bitlen_lld*/ for(i = 0; i != numcodes_ll; ++i) uivector_push_back(&bitlen_lld, HuffmanTree_getLength(&tree_ll, (unsigned)i)); for(i = 0; i != numcodes_d; ++i) uivector_push_back(&bitlen_lld, HuffmanTree_getLength(&tree_d, (unsigned)i)); /*run-length compress bitlen_ldd into bitlen_lld_e by using repeat codes 16 (copy length 3-6 times), 17 (3-10 zeroes), 18 (11-138 zeroes)*/ for(i = 0; i != (unsigned)bitlen_lld.size; ++i) { unsigned j = 0; /*amount of repititions*/ while(i + j + 1 < (unsigned)bitlen_lld.size && bitlen_lld.data[i + j + 1] == bitlen_lld.data[i]) ++j; if(bitlen_lld.data[i] == 0 && j >= 2) /*repeat code for zeroes*/ { ++j; /*include the first zero*/ if(j <= 10) /*repeat code 17 supports max 10 zeroes*/ { uivector_push_back(&bitlen_lld_e, 17); uivector_push_back(&bitlen_lld_e, j - 3); } else /*repeat code 18 supports max 138 zeroes*/ { if(j > 138) j = 138; uivector_push_back(&bitlen_lld_e, 18); uivector_push_back(&bitlen_lld_e, j - 11); } i += (j - 1); } else if(j >= 3) /*repeat code for value other than zero*/ { size_t k; unsigned num = j / 6, rest = j % 6; uivector_push_back(&bitlen_lld_e, bitlen_lld.data[i]); for(k = 0; k < num; ++k) { uivector_push_back(&bitlen_lld_e, 16); uivector_push_back(&bitlen_lld_e, 6 - 3); } if(rest >= 3) { uivector_push_back(&bitlen_lld_e, 16); uivector_push_back(&bitlen_lld_e, rest - 3); } else j -= rest; i += j; } else /*too short to benefit from repeat code*/ { uivector_push_back(&bitlen_lld_e, bitlen_lld.data[i]); } } /*generate tree_cl, the huffmantree of huffmantrees*/ if(!uivector_resizev(&frequencies_cl, NUM_CODE_LENGTH_CODES, 0)) ERROR_BREAK(83 /*alloc fail*/); for(i = 0; i != bitlen_lld_e.size; ++i) { ++frequencies_cl.data[bitlen_lld_e.data[i]]; /*after a repeat code come the bits that specify the number of repetitions, those don't need to be in the frequencies_cl calculation*/ if(bitlen_lld_e.data[i] >= 16) ++i; } error = HuffmanTree_makeFromFrequencies(&tree_cl, frequencies_cl.data, frequencies_cl.size, frequencies_cl.size, 7); if(error) break; if(!uivector_resize(&bitlen_cl, tree_cl.numcodes)) ERROR_BREAK(83 /*alloc fail*/); for(i = 0; i != tree_cl.numcodes; ++i) { /*lenghts of code length tree is in the order as specified by deflate*/ bitlen_cl.data[i] = HuffmanTree_getLength(&tree_cl, CLCL_ORDER[i]); } while(bitlen_cl.data[bitlen_cl.size - 1] == 0 && bitlen_cl.size > 4) { /*remove zeros at the end, but minimum size must be 4*/ if(!uivector_resize(&bitlen_cl, bitlen_cl.size - 1)) ERROR_BREAK(83 /*alloc fail*/); } if(error) break; /* Write everything into the output After the BFINAL and BTYPE, the dynamic block consists out of the following: - 5 bits HLIT, 5 bits HDIST, 4 bits HCLEN - (HCLEN+4)*3 bits code lengths of code length alphabet - HLIT + 257 code lenghts of lit/length alphabet (encoded using the code length alphabet, + possible repetition codes 16, 17, 18) - HDIST + 1 code lengths of distance alphabet (encoded using the code length alphabet, + possible repetition codes 16, 17, 18) - compressed data - 256 (end code) */ /*Write block type*/ addBitToStream(bp, out, BFINAL); addBitToStream(bp, out, 0); /*first bit of BTYPE "dynamic"*/ addBitToStream(bp, out, 1); /*second bit of BTYPE "dynamic"*/ /*write the HLIT, HDIST and HCLEN values*/ HLIT = (unsigned)(numcodes_ll - 257); HDIST = (unsigned)(numcodes_d - 1); HCLEN = (unsigned)bitlen_cl.size - 4; /*trim zeroes for HCLEN. HLIT and HDIST were already trimmed at tree creation*/ while(!bitlen_cl.data[HCLEN + 4 - 1] && HCLEN > 0) --HCLEN; addBitsToStream(bp, out, HLIT, 5); addBitsToStream(bp, out, HDIST, 5); addBitsToStream(bp, out, HCLEN, 4); /*write the code lenghts of the code length alphabet*/ for(i = 0; i != HCLEN + 4; ++i) addBitsToStream(bp, out, bitlen_cl.data[i], 3); /*write the lenghts of the lit/len AND the dist alphabet*/ for(i = 0; i != bitlen_lld_e.size; ++i) { addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_cl, bitlen_lld_e.data[i]), HuffmanTree_getLength(&tree_cl, bitlen_lld_e.data[i])); /*extra bits of repeat codes*/ if(bitlen_lld_e.data[i] == 16) addBitsToStream(bp, out, bitlen_lld_e.data[++i], 2); else if(bitlen_lld_e.data[i] == 17) addBitsToStream(bp, out, bitlen_lld_e.data[++i], 3); else if(bitlen_lld_e.data[i] == 18) addBitsToStream(bp, out, bitlen_lld_e.data[++i], 7); } /*write the compressed data symbols*/ writeLZ77data(bp, out, &lz77_encoded, &tree_ll, &tree_d); /*error: the length of the end code 256 must be larger than 0*/ if(HuffmanTree_getLength(&tree_ll, 256) == 0) ERROR_BREAK(64); /*write the end code*/ addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_ll, 256), HuffmanTree_getLength(&tree_ll, 256)); break; /*end of error-while*/ } /*cleanup*/ uivector_cleanup(&lz77_encoded); HuffmanTree_cleanup(&tree_ll); HuffmanTree_cleanup(&tree_d); HuffmanTree_cleanup(&tree_cl); uivector_cleanup(&frequencies_ll); uivector_cleanup(&frequencies_d); uivector_cleanup(&frequencies_cl); uivector_cleanup(&bitlen_lld_e); uivector_cleanup(&bitlen_lld); uivector_cleanup(&bitlen_cl); return error; } static unsigned deflateFixed(ucvector* out, size_t* bp, Hash* hash, const unsigned char* data, size_t datapos, size_t dataend, const LodePNGCompressSettings* settings, unsigned final) { HuffmanTree tree_ll; /*tree for literal values and length codes*/ HuffmanTree tree_d; /*tree for distance codes*/ unsigned BFINAL = final; unsigned error = 0; size_t i; HuffmanTree_init(&tree_ll); HuffmanTree_init(&tree_d); generateFixedLitLenTree(&tree_ll); generateFixedDistanceTree(&tree_d); addBitToStream(bp, out, BFINAL); addBitToStream(bp, out, 1); /*first bit of BTYPE*/ addBitToStream(bp, out, 0); /*second bit of BTYPE*/ if(settings->use_lz77) /*LZ77 encoded*/ { uivector lz77_encoded; uivector_init(&lz77_encoded); error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->windowsize, settings->minmatch, settings->nicematch, settings->lazymatching); if(!error) writeLZ77data(bp, out, &lz77_encoded, &tree_ll, &tree_d); uivector_cleanup(&lz77_encoded); } else /*no LZ77, but still will be Huffman compressed*/ { for(i = datapos; i < dataend; ++i) { addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_ll, data[i]), HuffmanTree_getLength(&tree_ll, data[i])); } } /*add END code*/ if(!error) addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_ll, 256), HuffmanTree_getLength(&tree_ll, 256)); /*cleanup*/ HuffmanTree_cleanup(&tree_ll); HuffmanTree_cleanup(&tree_d); return error; } static unsigned lodepng_deflatev(ucvector* out, const unsigned char* in, size_t insize, const LodePNGCompressSettings* settings) { unsigned error = 0; size_t i, blocksize, numdeflateblocks; size_t bp = 0; /*the bit pointer*/ Hash hash; if(settings->btype > 2) return 61; else if(settings->btype == 0) return deflateNoCompression(out, in, insize); else if(settings->btype == 1) blocksize = insize; else /*if(settings->btype == 2)*/ { /*on PNGs, deflate blocks of 65-262k seem to give most dense encoding*/ blocksize = insize / 8 + 8; if(blocksize < 65536) blocksize = 65536; if(blocksize > 262144) blocksize = 262144; } numdeflateblocks = (insize + blocksize - 1) / blocksize; if(numdeflateblocks == 0) numdeflateblocks = 1; error = hash_init(&hash, settings->windowsize); if(error) return error; for(i = 0; i != numdeflateblocks && !error; ++i) { unsigned final = (i == numdeflateblocks - 1); size_t start = i * blocksize; size_t end = start + blocksize; if(end > insize) end = insize; if(settings->btype == 1) error = deflateFixed(out, &bp, &hash, in, start, end, settings, final); else if(settings->btype == 2) error = deflateDynamic(out, &bp, &hash, in, start, end, settings, final); } hash_cleanup(&hash); return error; } unsigned lodepng_deflate(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGCompressSettings* settings) { unsigned error; ucvector v; ucvector_init_buffer(&v, *out, *outsize); error = lodepng_deflatev(&v, in, insize, settings); *out = v.data; *outsize = v.size; return error; } static unsigned deflate(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGCompressSettings* settings) { if(settings->custom_deflate) { return settings->custom_deflate(out, outsize, in, insize, settings); } else { return lodepng_deflate(out, outsize, in, insize, settings); } } #endif /*LODEPNG_COMPILE_DECODER*/ /* ////////////////////////////////////////////////////////////////////////// */ /* / Adler32 */ /* ////////////////////////////////////////////////////////////////////////// */ static unsigned update_adler32(unsigned adler, const unsigned char* data, unsigned len) { unsigned s1 = adler & 0xffff; unsigned s2 = (adler >> 16) & 0xffff; while(len > 0) { /*at least 5550 sums can be done before the sums overflow, saving a lot of module divisions*/ unsigned amount = len > 5550 ? 5550 : len; len -= amount; while(amount > 0) { s1 += (*data++); s2 += s1; --amount; } s1 %= 65521; s2 %= 65521; } return (s2 << 16) | s1; } /*Return the adler32 of the bytes data[0..len-1]*/ static unsigned adler32(const unsigned char* data, unsigned len) { return update_adler32(1L, data, len); } /* ////////////////////////////////////////////////////////////////////////// */ /* / Zlib / */ /* ////////////////////////////////////////////////////////////////////////// */ #ifdef LODEPNG_COMPILE_DECODER unsigned lodepng_zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings) { unsigned error = 0; unsigned CM, CINFO, FDICT; if(insize < 2) return 53; /*error, size of zlib data too small*/ /*read information from zlib header*/ if((in[0] * 256 + in[1]) % 31 != 0) { /*error: 256 * in[0] + in[1] must be a multiple of 31, the FCHECK value is supposed to be made that way*/ return 24; } CM = in[0] & 15; CINFO = (in[0] >> 4) & 15; /*FCHECK = in[1] & 31;*/ /*FCHECK is already tested above*/ FDICT = (in[1] >> 5) & 1; /*FLEVEL = (in[1] >> 6) & 3;*/ /*FLEVEL is not used here*/ if(CM != 8 || CINFO > 7) { /*error: only compression method 8: inflate with sliding window of 32k is supported by the PNG spec*/ return 25; } if(FDICT != 0) { /*error: the specification of PNG says about the zlib stream: "The additional flags shall not specify a preset dictionary."*/ return 26; } error = inflate(out, outsize, in + 2, insize - 2, settings); if(error) return error; if(!settings->ignore_adler32) { unsigned ADLER32 = lodepng_read32bitInt(&in[insize - 4]); unsigned checksum = adler32(*out, (unsigned)(*outsize)); if(checksum != ADLER32) return 58; /*error, adler checksum not correct, data must be corrupted*/ } return 0; /*no error*/ } static unsigned zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings) { if(settings->custom_zlib) { return settings->custom_zlib(out, outsize, in, insize, settings); } else { return lodepng_zlib_decompress(out, outsize, in, insize, settings); } } #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGCompressSettings* settings) { /*initially, *out must be NULL and outsize 0, if you just give some random *out that's pointing to a non allocated buffer, this'll crash*/ ucvector outv; size_t i; unsigned error; unsigned char* deflatedata = 0; size_t deflatesize = 0; /*zlib data: 1 byte CMF (CM+CINFO), 1 byte FLG, deflate data, 4 byte ADLER32 checksum of the Decompressed data*/ unsigned CMF = 120; /*0b01111000: CM 8, CINFO 7. With CINFO 7, any window size up to 32768 can be used.*/ unsigned FLEVEL = 0; unsigned FDICT = 0; unsigned CMFFLG = 256 * CMF + FDICT * 32 + FLEVEL * 64; unsigned FCHECK = 31 - CMFFLG % 31; CMFFLG += FCHECK; /*ucvector-controlled version of the output buffer, for dynamic array*/ ucvector_init_buffer(&outv, *out, *outsize); ucvector_push_back(&outv, (unsigned char)(CMFFLG >> 8)); ucvector_push_back(&outv, (unsigned char)(CMFFLG & 255)); error = deflate(&deflatedata, &deflatesize, in, insize, settings); if(!error) { unsigned ADLER32 = adler32(in, (unsigned)insize); for(i = 0; i != deflatesize; ++i) ucvector_push_back(&outv, deflatedata[i]); lodepng_free(deflatedata); lodepng_add32bitInt(&outv, ADLER32); } *out = outv.data; *outsize = outv.size; return error; } /* compress using the default or custom zlib function */ static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGCompressSettings* settings) { if(settings->custom_zlib) { return settings->custom_zlib(out, outsize, in, insize, settings); } else { return lodepng_zlib_compress(out, outsize, in, insize, settings); } } #endif /*LODEPNG_COMPILE_ENCODER*/ #else /*no LODEPNG_COMPILE_ZLIB*/ #ifdef LODEPNG_COMPILE_DECODER static unsigned zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings) { if(!settings->custom_zlib) return 87; /*no custom zlib function provided */ return settings->custom_zlib(out, outsize, in, insize, settings); } #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGCompressSettings* settings) { if(!settings->custom_zlib) return 87; /*no custom zlib function provided */ return settings->custom_zlib(out, outsize, in, insize, settings); } #endif /*LODEPNG_COMPILE_ENCODER*/ #endif /*LODEPNG_COMPILE_ZLIB*/ /* ////////////////////////////////////////////////////////////////////////// */ #ifdef LODEPNG_COMPILE_ENCODER /*this is a good tradeoff between speed and compression ratio*/ #define DEFAULT_WINDOWSIZE 2048 void lodepng_compress_settings_init(LodePNGCompressSettings* settings) { /*compress with dynamic huffman tree (not in the mathematical sense, just not the predefined one)*/ settings->btype = 2; settings->use_lz77 = 1; settings->windowsize = DEFAULT_WINDOWSIZE; settings->minmatch = 3; settings->nicematch = 128; settings->lazymatching = 1; settings->custom_zlib = 0; settings->custom_deflate = 0; settings->custom_context = 0; } const LodePNGCompressSettings lodepng_default_compress_settings = {2, 1, DEFAULT_WINDOWSIZE, 3, 128, 1, 0, 0, 0}; #endif /*LODEPNG_COMPILE_ENCODER*/ #ifdef LODEPNG_COMPILE_DECODER void lodepng_decompress_settings_init(LodePNGDecompressSettings* settings) { settings->ignore_adler32 = 0; settings->custom_zlib = 0; settings->custom_inflate = 0; settings->custom_context = 0; } const LodePNGDecompressSettings lodepng_default_decompress_settings = {0, 0, 0, 0}; #endif /*LODEPNG_COMPILE_DECODER*/ /* ////////////////////////////////////////////////////////////////////////// */ /* ////////////////////////////////////////////////////////////////////////// */ /* // End of Zlib related code. Begin of PNG related code. // */ /* ////////////////////////////////////////////////////////////////////////// */ /* ////////////////////////////////////////////////////////////////////////// */ #ifdef LODEPNG_COMPILE_PNG /* ////////////////////////////////////////////////////////////////////////// */ /* / CRC32 / */ /* ////////////////////////////////////////////////////////////////////////// */ #ifndef LODEPNG_NO_COMPILE_CRC /* CRC polynomial: 0xedb88320 */ static unsigned lodepng_crc32_table[256] = { 0u, 1996959894u, 3993919788u, 2567524794u, 124634137u, 1886057615u, 3915621685u, 2657392035u, 249268274u, 2044508324u, 3772115230u, 2547177864u, 162941995u, 2125561021u, 3887607047u, 2428444049u, 498536548u, 1789927666u, 4089016648u, 2227061214u, 450548861u, 1843258603u, 4107580753u, 2211677639u, 325883990u, 1684777152u, 4251122042u, 2321926636u, 335633487u, 1661365465u, 4195302755u, 2366115317u, 997073096u, 1281953886u, 3579855332u, 2724688242u, 1006888145u, 1258607687u, 3524101629u, 2768942443u, 901097722u, 1119000684u, 3686517206u, 2898065728u, 853044451u, 1172266101u, 3705015759u, 2882616665u, 651767980u, 1373503546u, 3369554304u, 3218104598u, 565507253u, 1454621731u, 3485111705u, 3099436303u, 671266974u, 1594198024u, 3322730930u, 2970347812u, 795835527u, 1483230225u, 3244367275u, 3060149565u, 1994146192u, 31158534u, 2563907772u, 4023717930u, 1907459465u, 112637215u, 2680153253u, 3904427059u, 2013776290u, 251722036u, 2517215374u, 3775830040u, 2137656763u, 141376813u, 2439277719u, 3865271297u, 1802195444u, 476864866u, 2238001368u, 4066508878u, 1812370925u, 453092731u, 2181625025u, 4111451223u, 1706088902u, 314042704u, 2344532202u, 4240017532u, 1658658271u, 366619977u, 2362670323u, 4224994405u, 1303535960u, 984961486u, 2747007092u, 3569037538u, 1256170817u, 1037604311u, 2765210733u, 3554079995u, 1131014506u, 879679996u, 2909243462u, 3663771856u, 1141124467u, 855842277u, 2852801631u, 3708648649u, 1342533948u, 654459306u, 3188396048u, 3373015174u, 1466479909u, 544179635u, 3110523913u, 3462522015u, 1591671054u, 702138776u, 2966460450u, 3352799412u, 1504918807u, 783551873u, 3082640443u, 3233442989u, 3988292384u, 2596254646u, 62317068u, 1957810842u, 3939845945u, 2647816111u, 81470997u, 1943803523u, 3814918930u, 2489596804u, 225274430u, 2053790376u, 3826175755u, 2466906013u, 167816743u, 2097651377u, 4027552580u, 2265490386u, 503444072u, 1762050814u, 4150417245u, 2154129355u, 426522225u, 1852507879u, 4275313526u, 2312317920u, 282753626u, 1742555852u, 4189708143u, 2394877945u, 397917763u, 1622183637u, 3604390888u, 2714866558u, 953729732u, 1340076626u, 3518719985u, 2797360999u, 1068828381u, 1219638859u, 3624741850u, 2936675148u, 906185462u, 1090812512u, 3747672003u, 2825379669u, 829329135u, 1181335161u, 3412177804u, 3160834842u, 628085408u, 1382605366u, 3423369109u, 3138078467u, 570562233u, 1426400815u, 3317316542u, 2998733608u, 733239954u, 1555261956u, 3268935591u, 3050360625u, 752459403u, 1541320221u, 2607071920u, 3965973030u, 1969922972u, 40735498u, 2617837225u, 3943577151u, 1913087877u, 83908371u, 2512341634u, 3803740692u, 2075208622u, 213261112u, 2463272603u, 3855990285u, 2094854071u, 198958881u, 2262029012u, 4057260610u, 1759359992u, 534414190u, 2176718541u, 4139329115u, 1873836001u, 414664567u, 2282248934u, 4279200368u, 1711684554u, 285281116u, 2405801727u, 4167216745u, 1634467795u, 376229701u, 2685067896u, 3608007406u, 1308918612u, 956543938u, 2808555105u, 3495958263u, 1231636301u, 1047427035u, 2932959818u, 3654703836u, 1088359270u, 936918000u, 2847714899u, 3736837829u, 1202900863u, 817233897u, 3183342108u, 3401237130u, 1404277552u, 615818150u, 3134207493u, 3453421203u, 1423857449u, 601450431u, 3009837614u, 3294710456u, 1567103746u, 711928724u, 3020668471u, 3272380065u, 1510334235u, 755167117u }; /*Return the CRC of the bytes buf[0..len-1].*/ unsigned lodepng_crc32(const unsigned char* data, size_t length) { unsigned r = 0xffffffffu; size_t i; for(i = 0; i < length; ++i) { r = lodepng_crc32_table[(r ^ data[i]) & 0xff] ^ (r >> 8); } return r ^ 0xffffffffu; } #else /* !LODEPNG_NO_COMPILE_CRC */ unsigned lodepng_crc32(const unsigned char* data, size_t length); #endif /* !LODEPNG_NO_COMPILE_CRC */ /* ////////////////////////////////////////////////////////////////////////// */ /* / Reading and writing single bits and bytes from/to stream for LodePNG / */ /* ////////////////////////////////////////////////////////////////////////// */ static unsigned char readBitFromReversedStream(size_t* bitpointer, const unsigned char* bitstream) { unsigned char result = (unsigned char)((bitstream[(*bitpointer) >> 3] >> (7 - ((*bitpointer) & 0x7))) & 1); ++(*bitpointer); return result; } static unsigned readBitsFromReversedStream(size_t* bitpointer, const unsigned char* bitstream, size_t nbits) { unsigned result = 0; size_t i; for(i = 0 ; i < nbits; ++i) { result <<= 1; result |= (unsigned)readBitFromReversedStream(bitpointer, bitstream); } return result; } #ifdef LODEPNG_COMPILE_DECODER static void setBitOfReversedStream0(size_t* bitpointer, unsigned char* bitstream, unsigned char bit) { /*the current bit in bitstream must be 0 for this to work*/ if(bit) { /*earlier bit of huffman code is in a lesser significant bit of an earlier byte*/ bitstream[(*bitpointer) >> 3] |= (bit << (7 - ((*bitpointer) & 0x7))); } ++(*bitpointer); } #endif /*LODEPNG_COMPILE_DECODER*/ static void setBitOfReversedStream(size_t* bitpointer, unsigned char* bitstream, unsigned char bit) { /*the current bit in bitstream may be 0 or 1 for this to work*/ if(bit == 0) bitstream[(*bitpointer) >> 3] &= (unsigned char)(~(1 << (7 - ((*bitpointer) & 0x7)))); else bitstream[(*bitpointer) >> 3] |= (1 << (7 - ((*bitpointer) & 0x7))); ++(*bitpointer); } /* ////////////////////////////////////////////////////////////////////////// */ /* / PNG chunks / */ /* ////////////////////////////////////////////////////////////////////////// */ unsigned lodepng_chunk_length(const unsigned char* chunk) { return lodepng_read32bitInt(&chunk[0]); } void lodepng_chunk_type(char type[5], const unsigned char* chunk) { unsigned i; for(i = 0; i != 4; ++i) type[i] = (char)chunk[4 + i]; type[4] = 0; /*null termination char*/ } unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type) { if(strlen(type) != 4) return 0; return (chunk[4] == type[0] && chunk[5] == type[1] && chunk[6] == type[2] && chunk[7] == type[3]); } unsigned char lodepng_chunk_ancillary(const unsigned char* chunk) { return((chunk[4] & 32) != 0); } unsigned char lodepng_chunk_private(const unsigned char* chunk) { return((chunk[6] & 32) != 0); } unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk) { return((chunk[7] & 32) != 0); } unsigned char* lodepng_chunk_data(unsigned char* chunk) { return &chunk[8]; } const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk) { return &chunk[8]; } unsigned lodepng_chunk_check_crc(const unsigned char* chunk) { unsigned length = lodepng_chunk_length(chunk); unsigned CRC = lodepng_read32bitInt(&chunk[length + 8]); /*the CRC is taken of the data and the 4 chunk type letters, not the length*/ unsigned checksum = lodepng_crc32(&chunk[4], length + 4); if(CRC != checksum) return 1; else return 0; } void lodepng_chunk_generate_crc(unsigned char* chunk) { unsigned length = lodepng_chunk_length(chunk); unsigned CRC = lodepng_crc32(&chunk[4], length + 4); lodepng_set32bitInt(chunk + 8 + length, CRC); } unsigned char* lodepng_chunk_next(unsigned char* chunk) { unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12; return &chunk[total_chunk_length]; } const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk) { unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12; return &chunk[total_chunk_length]; } unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsigned char* chunk) { unsigned i; unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12; unsigned char *chunk_start, *new_buffer; size_t new_length = (*outlength) + total_chunk_length; if(new_length < total_chunk_length || new_length < (*outlength)) return 77; /*integer overflow happened*/ new_buffer = (unsigned char*)lodepng_realloc(*out, new_length); if(!new_buffer) return 83; /*alloc fail*/ (*out) = new_buffer; (*outlength) = new_length; chunk_start = &(*out)[new_length - total_chunk_length]; for(i = 0; i != total_chunk_length; ++i) chunk_start[i] = chunk[i]; return 0; } unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length, const char* type, const unsigned char* data) { unsigned i; unsigned char *chunk, *new_buffer; size_t new_length = (*outlength) + length + 12; if(new_length < length + 12 || new_length < (*outlength)) return 77; /*integer overflow happened*/ new_buffer = (unsigned char*)lodepng_realloc(*out, new_length); if(!new_buffer) return 83; /*alloc fail*/ (*out) = new_buffer; (*outlength) = new_length; chunk = &(*out)[(*outlength) - length - 12]; /*1: length*/ lodepng_set32bitInt(chunk, (unsigned)length); /*2: chunk name (4 letters)*/ chunk[4] = (unsigned char)type[0]; chunk[5] = (unsigned char)type[1]; chunk[6] = (unsigned char)type[2]; chunk[7] = (unsigned char)type[3]; /*3: the data*/ for(i = 0; i != length; ++i) chunk[8 + i] = data[i]; /*4: CRC (of the chunkname characters and the data)*/ lodepng_chunk_generate_crc(chunk); return 0; } /* ////////////////////////////////////////////////////////////////////////// */ /* / Color types and such / */ /* ////////////////////////////////////////////////////////////////////////// */ /*return type is a LodePNG error code*/ static unsigned checkColorValidity(LodePNGColorType colortype, unsigned bd) /*bd = bitdepth*/ { switch(colortype) { case 0: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 || bd == 16)) return 37; break; /*grey*/ case 2: if(!( bd == 8 || bd == 16)) return 37; break; /*RGB*/ case 3: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 )) return 37; break; /*palette*/ case 4: if(!( bd == 8 || bd == 16)) return 37; break; /*grey + alpha*/ case 6: if(!( bd == 8 || bd == 16)) return 37; break; /*RGBA*/ default: return 31; } return 0; /*allowed color type / bits combination*/ } static unsigned getNumColorChannels(LodePNGColorType colortype) { switch(colortype) { case 0: return 1; /*grey*/ case 2: return 3; /*RGB*/ case 3: return 1; /*palette*/ case 4: return 2; /*grey + alpha*/ case 6: return 4; /*RGBA*/ } return 0; /*unexisting color type*/ } static unsigned lodepng_get_bpp_lct(LodePNGColorType colortype, unsigned bitdepth) { /*bits per pixel is amount of channels * bits per channel*/ return getNumColorChannels(colortype) * bitdepth; } /* ////////////////////////////////////////////////////////////////////////// */ void lodepng_color_mode_init(LodePNGColorMode* info) { info->key_defined = 0; info->key_r = info->key_g = info->key_b = 0; info->colortype = LCT_RGBA; info->bitdepth = 8; info->palette = 0; info->palettesize = 0; } void lodepng_color_mode_cleanup(LodePNGColorMode* info) { lodepng_palette_clear(info); } unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* source) { size_t i; lodepng_color_mode_cleanup(dest); *dest = *source; if(source->palette) { dest->palette = (unsigned char*)lodepng_malloc(1024); if(!dest->palette && source->palettesize) return 83; /*alloc fail*/ for(i = 0; i != source->palettesize * 4; ++i) dest->palette[i] = source->palette[i]; } return 0; } static int lodepng_color_mode_equal(const LodePNGColorMode* a, const LodePNGColorMode* b) { size_t i; if(a->colortype != b->colortype) return 0; if(a->bitdepth != b->bitdepth) return 0; if(a->key_defined != b->key_defined) return 0; if(a->key_defined) { if(a->key_r != b->key_r) return 0; if(a->key_g != b->key_g) return 0; if(a->key_b != b->key_b) return 0; } /*if one of the palette sizes is 0, then we consider it to be the same as the other: it means that e.g. the palette was not given by the user and should be considered the same as the palette inside the PNG.*/ if(1/*a->palettesize != 0 && b->palettesize != 0*/) { if(a->palettesize != b->palettesize) return 0; for(i = 0; i != a->palettesize * 4; ++i) { if(a->palette[i] != b->palette[i]) return 0; } } return 1; } void lodepng_palette_clear(LodePNGColorMode* info) { if(info->palette) lodepng_free(info->palette); info->palette = 0; info->palettesize = 0; } unsigned lodepng_palette_add(LodePNGColorMode* info, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { unsigned char* data; /*the same resize technique as C++ std::vectors is used, and here it's made so that for a palette with the max of 256 colors, it'll have the exact alloc size*/ if(!info->palette) /*allocate palette if empty*/ { /*room for 256 colors with 4 bytes each*/ data = (unsigned char*)lodepng_realloc(info->palette, 1024); if(!data) return 83; /*alloc fail*/ else info->palette = data; } info->palette[4 * info->palettesize + 0] = r; info->palette[4 * info->palettesize + 1] = g; info->palette[4 * info->palettesize + 2] = b; info->palette[4 * info->palettesize + 3] = a; ++info->palettesize; return 0; } unsigned lodepng_get_bpp(const LodePNGColorMode* info) { /*calculate bits per pixel out of colortype and bitdepth*/ return lodepng_get_bpp_lct(info->colortype, info->bitdepth); } unsigned lodepng_get_channels(const LodePNGColorMode* info) { return getNumColorChannels(info->colortype); } unsigned lodepng_is_greyscale_type(const LodePNGColorMode* info) { return info->colortype == LCT_GREY || info->colortype == LCT_GREY_ALPHA; } unsigned lodepng_is_alpha_type(const LodePNGColorMode* info) { return (info->colortype & 4) != 0; /*4 or 6*/ } unsigned lodepng_is_palette_type(const LodePNGColorMode* info) { return info->colortype == LCT_PALETTE; } unsigned lodepng_has_palette_alpha(const LodePNGColorMode* info) { size_t i; for(i = 0; i != info->palettesize; ++i) { if(info->palette[i * 4 + 3] < 255) return 1; } return 0; } unsigned lodepng_can_have_alpha(const LodePNGColorMode* info) { return info->key_defined || lodepng_is_alpha_type(info) || lodepng_has_palette_alpha(info); } size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* color) { /*will not overflow for any color type if roughly w * h < 268435455*/ size_t bpp = lodepng_get_bpp(color); size_t n = w * h; return ((n / 8) * bpp) + ((n & 7) * bpp + 7) / 8; } size_t lodepng_get_raw_size_lct(unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) { /*will not overflow for any color type if roughly w * h < 268435455*/ size_t bpp = lodepng_get_bpp_lct(colortype, bitdepth); size_t n = w * h; return ((n / 8) * bpp) + ((n & 7) * bpp + 7) / 8; } #ifdef LODEPNG_COMPILE_PNG #ifdef LODEPNG_COMPILE_DECODER /*in an idat chunk, each scanline is a multiple of 8 bits, unlike the lodepng output buffer*/ static size_t lodepng_get_raw_size_idat(unsigned w, unsigned h, const LodePNGColorMode* color) { /*will not overflow for any color type if roughly w * h < 268435455*/ size_t bpp = lodepng_get_bpp(color); size_t line = ((w / 8) * bpp) + ((w & 7) * bpp + 7) / 8; return h * line; } #endif /*LODEPNG_COMPILE_DECODER*/ #endif /*LODEPNG_COMPILE_PNG*/ #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS static void LodePNGUnknownChunks_init(LodePNGInfo* info) { unsigned i; for(i = 0; i != 3; ++i) info->unknown_chunks_data[i] = 0; for(i = 0; i != 3; ++i) info->unknown_chunks_size[i] = 0; } static void LodePNGUnknownChunks_cleanup(LodePNGInfo* info) { unsigned i; for(i = 0; i != 3; ++i) lodepng_free(info->unknown_chunks_data[i]); } static unsigned LodePNGUnknownChunks_copy(LodePNGInfo* dest, const LodePNGInfo* src) { unsigned i; LodePNGUnknownChunks_cleanup(dest); for(i = 0; i != 3; ++i) { size_t j; dest->unknown_chunks_size[i] = src->unknown_chunks_size[i]; dest->unknown_chunks_data[i] = (unsigned char*)lodepng_malloc(src->unknown_chunks_size[i]); if(!dest->unknown_chunks_data[i] && dest->unknown_chunks_size[i]) return 83; /*alloc fail*/ for(j = 0; j < src->unknown_chunks_size[i]; ++j) { dest->unknown_chunks_data[i][j] = src->unknown_chunks_data[i][j]; } } return 0; } /******************************************************************************/ static void LodePNGText_init(LodePNGInfo* info) { info->text_num = 0; info->text_keys = NULL; info->text_strings = NULL; } static void LodePNGText_cleanup(LodePNGInfo* info) { size_t i; for(i = 0; i != info->text_num; ++i) { string_cleanup(&info->text_keys[i]); string_cleanup(&info->text_strings[i]); } lodepng_free(info->text_keys); lodepng_free(info->text_strings); } static unsigned LodePNGText_copy(LodePNGInfo* dest, const LodePNGInfo* source) { size_t i = 0; dest->text_keys = 0; dest->text_strings = 0; dest->text_num = 0; for(i = 0; i != source->text_num; ++i) { CERROR_TRY_RETURN(lodepng_add_text(dest, source->text_keys[i], source->text_strings[i])); } return 0; } void lodepng_clear_text(LodePNGInfo* info) { LodePNGText_cleanup(info); } unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str) { char** new_keys = (char**)(lodepng_realloc(info->text_keys, sizeof(char*) * (info->text_num + 1))); char** new_strings = (char**)(lodepng_realloc(info->text_strings, sizeof(char*) * (info->text_num + 1))); if(!new_keys || !new_strings) { lodepng_free(new_keys); lodepng_free(new_strings); return 83; /*alloc fail*/ } ++info->text_num; info->text_keys = new_keys; info->text_strings = new_strings; string_init(&info->text_keys[info->text_num - 1]); string_set(&info->text_keys[info->text_num - 1], key); string_init(&info->text_strings[info->text_num - 1]); string_set(&info->text_strings[info->text_num - 1], str); return 0; } /******************************************************************************/ static void LodePNGIText_init(LodePNGInfo* info) { info->itext_num = 0; info->itext_keys = NULL; info->itext_langtags = NULL; info->itext_transkeys = NULL; info->itext_strings = NULL; } static void LodePNGIText_cleanup(LodePNGInfo* info) { size_t i; for(i = 0; i != info->itext_num; ++i) { string_cleanup(&info->itext_keys[i]); string_cleanup(&info->itext_langtags[i]); string_cleanup(&info->itext_transkeys[i]); string_cleanup(&info->itext_strings[i]); } lodepng_free(info->itext_keys); lodepng_free(info->itext_langtags); lodepng_free(info->itext_transkeys); lodepng_free(info->itext_strings); } static unsigned LodePNGIText_copy(LodePNGInfo* dest, const LodePNGInfo* source) { size_t i = 0; dest->itext_keys = 0; dest->itext_langtags = 0; dest->itext_transkeys = 0; dest->itext_strings = 0; dest->itext_num = 0; for(i = 0; i != source->itext_num; ++i) { CERROR_TRY_RETURN(lodepng_add_itext(dest, source->itext_keys[i], source->itext_langtags[i], source->itext_transkeys[i], source->itext_strings[i])); } return 0; } void lodepng_clear_itext(LodePNGInfo* info) { LodePNGIText_cleanup(info); } unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag, const char* transkey, const char* str) { char** new_keys = (char**)(lodepng_realloc(info->itext_keys, sizeof(char*) * (info->itext_num + 1))); char** new_langtags = (char**)(lodepng_realloc(info->itext_langtags, sizeof(char*) * (info->itext_num + 1))); char** new_transkeys = (char**)(lodepng_realloc(info->itext_transkeys, sizeof(char*) * (info->itext_num + 1))); char** new_strings = (char**)(lodepng_realloc(info->itext_strings, sizeof(char*) * (info->itext_num + 1))); if(!new_keys || !new_langtags || !new_transkeys || !new_strings) { lodepng_free(new_keys); lodepng_free(new_langtags); lodepng_free(new_transkeys); lodepng_free(new_strings); return 83; /*alloc fail*/ } ++info->itext_num; info->itext_keys = new_keys; info->itext_langtags = new_langtags; info->itext_transkeys = new_transkeys; info->itext_strings = new_strings; string_init(&info->itext_keys[info->itext_num - 1]); string_set(&info->itext_keys[info->itext_num - 1], key); string_init(&info->itext_langtags[info->itext_num - 1]); string_set(&info->itext_langtags[info->itext_num - 1], langtag); string_init(&info->itext_transkeys[info->itext_num - 1]); string_set(&info->itext_transkeys[info->itext_num - 1], transkey); string_init(&info->itext_strings[info->itext_num - 1]); string_set(&info->itext_strings[info->itext_num - 1], str); return 0; } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ void lodepng_info_init(LodePNGInfo* info) { lodepng_color_mode_init(&info->color); info->interlace_method = 0; info->compression_method = 0; info->filter_method = 0; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS info->background_defined = 0; info->background_r = info->background_g = info->background_b = 0; LodePNGText_init(info); LodePNGIText_init(info); info->time_defined = 0; info->phys_defined = 0; LodePNGUnknownChunks_init(info); #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } void lodepng_info_cleanup(LodePNGInfo* info) { lodepng_color_mode_cleanup(&info->color); #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS LodePNGText_cleanup(info); LodePNGIText_cleanup(info); LodePNGUnknownChunks_cleanup(info); #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source) { lodepng_info_cleanup(dest); *dest = *source; lodepng_color_mode_init(&dest->color); CERROR_TRY_RETURN(lodepng_color_mode_copy(&dest->color, &source->color)); #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS CERROR_TRY_RETURN(LodePNGText_copy(dest, source)); CERROR_TRY_RETURN(LodePNGIText_copy(dest, source)); LodePNGUnknownChunks_init(dest); CERROR_TRY_RETURN(LodePNGUnknownChunks_copy(dest, source)); #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ return 0; } void lodepng_info_swap(LodePNGInfo* a, LodePNGInfo* b) { LodePNGInfo temp = *a; *a = *b; *b = temp; } /* ////////////////////////////////////////////////////////////////////////// */ /*index: bitgroup index, bits: bitgroup size(1, 2 or 4), in: bitgroup value, out: octet array to add bits to*/ static void addColorBits(unsigned char* out, size_t index, unsigned bits, unsigned in) { unsigned m = bits == 1 ? 7 : bits == 2 ? 3 : 1; /*8 / bits - 1*/ /*p = the partial index in the byte, e.g. with 4 palettebits it is 0 for first half or 1 for second half*/ unsigned p = index & m; in &= (1u << bits) - 1u; /*filter out any other bits of the input value*/ in = in << (bits * (m - p)); if(p == 0) out[index * bits / 8] = in; else out[index * bits / 8] |= in; } typedef struct ColorTree ColorTree; /* One node of a color tree This is the data structure used to count the number of unique colors and to get a palette index for a color. It's like an octree, but because the alpha channel is used too, each node has 16 instead of 8 children. */ struct ColorTree { ColorTree* children[16]; /*up to 16 pointers to ColorTree of next level*/ int index; /*the payload. Only has a meaningful value if this is in the last level*/ }; static void color_tree_init(ColorTree* tree) { int i; for(i = 0; i != 16; ++i) tree->children[i] = 0; tree->index = -1; } static void color_tree_cleanup(ColorTree* tree) { int i; for(i = 0; i != 16; ++i) { if(tree->children[i]) { color_tree_cleanup(tree->children[i]); lodepng_free(tree->children[i]); } } } /*returns -1 if color not present, its index otherwise*/ static int color_tree_get(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { int bit = 0; for(bit = 0; bit < 8; ++bit) { int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1); if(!tree->children[i]) return -1; else tree = tree->children[i]; } return tree ? tree->index : -1; } #ifdef LODEPNG_COMPILE_ENCODER static int color_tree_has(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { return color_tree_get(tree, r, g, b, a) >= 0; } #endif /*LODEPNG_COMPILE_ENCODER*/ /*color is not allowed to already exist. Index should be >= 0 (it's signed to be compatible with using -1 for "doesn't exist")*/ static void color_tree_add(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned index) { int bit; for(bit = 0; bit < 8; ++bit) { int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1); if(!tree->children[i]) { tree->children[i] = (ColorTree*)lodepng_malloc(sizeof(ColorTree)); color_tree_init(tree->children[i]); } tree = tree->children[i]; } tree->index = (int)index; } /*put a pixel, given its RGBA color, into image of any color type*/ static unsigned rgba8ToPixel(unsigned char* out, size_t i, const LodePNGColorMode* mode, ColorTree* tree /*for palette*/, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { if(mode->colortype == LCT_GREY) { unsigned char grey = r; /*((unsigned short)r + g + b) / 3*/; if(mode->bitdepth == 8) out[i] = grey; else if(mode->bitdepth == 16) out[i * 2 + 0] = out[i * 2 + 1] = grey; else { /*take the most significant bits of grey*/ grey = (grey >> (8 - mode->bitdepth)) & ((1 << mode->bitdepth) - 1); addColorBits(out, i, mode->bitdepth, grey); } } else if(mode->colortype == LCT_RGB) { if(mode->bitdepth == 8) { out[i * 3 + 0] = r; out[i * 3 + 1] = g; out[i * 3 + 2] = b; } else { out[i * 6 + 0] = out[i * 6 + 1] = r; out[i * 6 + 2] = out[i * 6 + 3] = g; out[i * 6 + 4] = out[i * 6 + 5] = b; } } else if(mode->colortype == LCT_PALETTE) { int index = color_tree_get(tree, r, g, b, a); if(index < 0) return 82; /*color not in palette*/ if(mode->bitdepth == 8) out[i] = index; else addColorBits(out, i, mode->bitdepth, (unsigned)index); } else if(mode->colortype == LCT_GREY_ALPHA) { unsigned char grey = r; /*((unsigned short)r + g + b) / 3*/; if(mode->bitdepth == 8) { out[i * 2 + 0] = grey; out[i * 2 + 1] = a; } else if(mode->bitdepth == 16) { out[i * 4 + 0] = out[i * 4 + 1] = grey; out[i * 4 + 2] = out[i * 4 + 3] = a; } } else if(mode->colortype == LCT_RGBA) { if(mode->bitdepth == 8) { out[i * 4 + 0] = r; out[i * 4 + 1] = g; out[i * 4 + 2] = b; out[i * 4 + 3] = a; } else { out[i * 8 + 0] = out[i * 8 + 1] = r; out[i * 8 + 2] = out[i * 8 + 3] = g; out[i * 8 + 4] = out[i * 8 + 5] = b; out[i * 8 + 6] = out[i * 8 + 7] = a; } } return 0; /*no error*/ } /*put a pixel, given its RGBA16 color, into image of any color 16-bitdepth type*/ static void rgba16ToPixel(unsigned char* out, size_t i, const LodePNGColorMode* mode, unsigned short r, unsigned short g, unsigned short b, unsigned short a) { if(mode->colortype == LCT_GREY) { unsigned short grey = r; /*((unsigned)r + g + b) / 3*/; out[i * 2 + 0] = (grey >> 8) & 255; out[i * 2 + 1] = grey & 255; } else if(mode->colortype == LCT_RGB) { out[i * 6 + 0] = (r >> 8) & 255; out[i * 6 + 1] = r & 255; out[i * 6 + 2] = (g >> 8) & 255; out[i * 6 + 3] = g & 255; out[i * 6 + 4] = (b >> 8) & 255; out[i * 6 + 5] = b & 255; } else if(mode->colortype == LCT_GREY_ALPHA) { unsigned short grey = r; /*((unsigned)r + g + b) / 3*/; out[i * 4 + 0] = (grey >> 8) & 255; out[i * 4 + 1] = grey & 255; out[i * 4 + 2] = (a >> 8) & 255; out[i * 4 + 3] = a & 255; } else if(mode->colortype == LCT_RGBA) { out[i * 8 + 0] = (r >> 8) & 255; out[i * 8 + 1] = r & 255; out[i * 8 + 2] = (g >> 8) & 255; out[i * 8 + 3] = g & 255; out[i * 8 + 4] = (b >> 8) & 255; out[i * 8 + 5] = b & 255; out[i * 8 + 6] = (a >> 8) & 255; out[i * 8 + 7] = a & 255; } } /*Get RGBA8 color of pixel with index i (y * width + x) from the raw image with given color type.*/ static void getPixelColorRGBA8(unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a, const unsigned char* in, size_t i, const LodePNGColorMode* mode) { if(mode->colortype == LCT_GREY) { if(mode->bitdepth == 8) { *r = *g = *b = in[i]; if(mode->key_defined && *r == mode->key_r) *a = 0; else *a = 255; } else if(mode->bitdepth == 16) { *r = *g = *b = in[i * 2 + 0]; if(mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) *a = 0; else *a = 255; } else { unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/ size_t j = i * mode->bitdepth; unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth); *r = *g = *b = (value * 255) / highest; if(mode->key_defined && value == mode->key_r) *a = 0; else *a = 255; } } else if(mode->colortype == LCT_RGB) { if(mode->bitdepth == 8) { *r = in[i * 3 + 0]; *g = in[i * 3 + 1]; *b = in[i * 3 + 2]; if(mode->key_defined && *r == mode->key_r && *g == mode->key_g && *b == mode->key_b) *a = 0; else *a = 255; } else { *r = in[i * 6 + 0]; *g = in[i * 6 + 2]; *b = in[i * 6 + 4]; if(mode->key_defined && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0; else *a = 255; } } else if(mode->colortype == LCT_PALETTE) { unsigned index; if(mode->bitdepth == 8) index = in[i]; else { size_t j = i * mode->bitdepth; index = readBitsFromReversedStream(&j, in, mode->bitdepth); } if(index >= mode->palettesize) { /*This is an error according to the PNG spec, but common PNG decoders make it black instead. Done here too, slightly faster due to no error handling needed.*/ *r = *g = *b = 0; *a = 255; } else { *r = mode->palette[index * 4 + 0]; *g = mode->palette[index * 4 + 1]; *b = mode->palette[index * 4 + 2]; *a = mode->palette[index * 4 + 3]; } } else if(mode->colortype == LCT_GREY_ALPHA) { if(mode->bitdepth == 8) { *r = *g = *b = in[i * 2 + 0]; *a = in[i * 2 + 1]; } else { *r = *g = *b = in[i * 4 + 0]; *a = in[i * 4 + 2]; } } else if(mode->colortype == LCT_RGBA) { if(mode->bitdepth == 8) { *r = in[i * 4 + 0]; *g = in[i * 4 + 1]; *b = in[i * 4 + 2]; *a = in[i * 4 + 3]; } else { *r = in[i * 8 + 0]; *g = in[i * 8 + 2]; *b = in[i * 8 + 4]; *a = in[i * 8 + 6]; } } } /*Similar to getPixelColorRGBA8, but with all the for loops inside of the color mode test cases, optimized to convert the colors much faster, when converting to RGBA or RGB with 8 bit per cannel. buffer must be RGBA or RGB output with enough memory, if has_alpha is true the output is RGBA. mode has the color mode of the input buffer.*/ static void getPixelColorsRGBA8(unsigned char* buffer, size_t numpixels, unsigned has_alpha, const unsigned char* in, const LodePNGColorMode* mode) { unsigned num_channels = has_alpha ? 4 : 3; size_t i; if(mode->colortype == LCT_GREY) { if(mode->bitdepth == 8) { for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = buffer[1] = buffer[2] = in[i]; if(has_alpha) buffer[3] = mode->key_defined && in[i] == mode->key_r ? 0 : 255; } } else if(mode->bitdepth == 16) { for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = buffer[1] = buffer[2] = in[i * 2]; if(has_alpha) buffer[3] = mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r ? 0 : 255; } } else { unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/ size_t j = 0; for(i = 0; i != numpixels; ++i, buffer += num_channels) { unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth); buffer[0] = buffer[1] = buffer[2] = (value * 255) / highest; if(has_alpha) buffer[3] = mode->key_defined && value == mode->key_r ? 0 : 255; } } } else if(mode->colortype == LCT_RGB) { if(mode->bitdepth == 8) { for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = in[i * 3 + 0]; buffer[1] = in[i * 3 + 1]; buffer[2] = in[i * 3 + 2]; if(has_alpha) buffer[3] = mode->key_defined && buffer[0] == mode->key_r && buffer[1]== mode->key_g && buffer[2] == mode->key_b ? 0 : 255; } } else { for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = in[i * 6 + 0]; buffer[1] = in[i * 6 + 2]; buffer[2] = in[i * 6 + 4]; if(has_alpha) buffer[3] = mode->key_defined && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b ? 0 : 255; } } } else if(mode->colortype == LCT_PALETTE) { unsigned index; size_t j = 0; for(i = 0; i != numpixels; ++i, buffer += num_channels) { if(mode->bitdepth == 8) index = in[i]; else index = readBitsFromReversedStream(&j, in, mode->bitdepth); if(index >= mode->palettesize) { /*This is an error according to the PNG spec, but most PNG decoders make it black instead. Done here too, slightly faster due to no error handling needed.*/ buffer[0] = buffer[1] = buffer[2] = 0; if(has_alpha) buffer[3] = 255; } else { buffer[0] = mode->palette[index * 4 + 0]; buffer[1] = mode->palette[index * 4 + 1]; buffer[2] = mode->palette[index * 4 + 2]; if(has_alpha) buffer[3] = mode->palette[index * 4 + 3]; } } } else if(mode->colortype == LCT_GREY_ALPHA) { if(mode->bitdepth == 8) { for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = buffer[1] = buffer[2] = in[i * 2 + 0]; if(has_alpha) buffer[3] = in[i * 2 + 1]; } } else { for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = buffer[1] = buffer[2] = in[i * 4 + 0]; if(has_alpha) buffer[3] = in[i * 4 + 2]; } } } else if(mode->colortype == LCT_RGBA) { if(mode->bitdepth == 8) { for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = in[i * 4 + 0]; buffer[1] = in[i * 4 + 1]; buffer[2] = in[i * 4 + 2]; if(has_alpha) buffer[3] = in[i * 4 + 3]; } } else { for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = in[i * 8 + 0]; buffer[1] = in[i * 8 + 2]; buffer[2] = in[i * 8 + 4]; if(has_alpha) buffer[3] = in[i * 8 + 6]; } } } } /*Get RGBA16 color of pixel with index i (y * width + x) from the raw image with given color type, but the given color type must be 16-bit itself.*/ static void getPixelColorRGBA16(unsigned short* r, unsigned short* g, unsigned short* b, unsigned short* a, const unsigned char* in, size_t i, const LodePNGColorMode* mode) { if(mode->colortype == LCT_GREY) { *r = *g = *b = 256 * in[i * 2 + 0] + in[i * 2 + 1]; if(mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) *a = 0; else *a = 65535; } else if(mode->colortype == LCT_RGB) { *r = 256u * in[i * 6 + 0] + in[i * 6 + 1]; *g = 256u * in[i * 6 + 2] + in[i * 6 + 3]; *b = 256u * in[i * 6 + 4] + in[i * 6 + 5]; if(mode->key_defined && 256u * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r && 256u * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g && 256u * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0; else *a = 65535; } else if(mode->colortype == LCT_GREY_ALPHA) { *r = *g = *b = 256u * in[i * 4 + 0] + in[i * 4 + 1]; *a = 256u * in[i * 4 + 2] + in[i * 4 + 3]; } else if(mode->colortype == LCT_RGBA) { *r = 256u * in[i * 8 + 0] + in[i * 8 + 1]; *g = 256u * in[i * 8 + 2] + in[i * 8 + 3]; *b = 256u * in[i * 8 + 4] + in[i * 8 + 5]; *a = 256u * in[i * 8 + 6] + in[i * 8 + 7]; } } unsigned lodepng_convert(unsigned char* out, const unsigned char* in, const LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, unsigned w, unsigned h) { size_t i; ColorTree tree; size_t numpixels = w * h; if(lodepng_color_mode_equal(mode_out, mode_in)) { size_t numbytes = lodepng_get_raw_size(w, h, mode_in); for(i = 0; i != numbytes; ++i) out[i] = in[i]; return 0; } if(mode_out->colortype == LCT_PALETTE) { size_t palettesize = mode_out->palettesize; const unsigned char* palette = mode_out->palette; size_t palsize = 1u << mode_out->bitdepth; /*if the user specified output palette but did not give the values, assume they want the values of the input color type (assuming that one is palette). Note that we never create a new palette ourselves.*/ if(palettesize == 0) { palettesize = mode_in->palettesize; palette = mode_in->palette; } if(palettesize < palsize) palsize = palettesize; color_tree_init(&tree); for(i = 0; i != palsize; ++i) { const unsigned char* p = &palette[i * 4]; color_tree_add(&tree, p[0], p[1], p[2], p[3], i); } } if(mode_in->bitdepth == 16 && mode_out->bitdepth == 16) { for(i = 0; i != numpixels; ++i) { unsigned short r = 0, g = 0, b = 0, a = 0; getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in); rgba16ToPixel(out, i, mode_out, r, g, b, a); } } else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGBA) { getPixelColorsRGBA8(out, numpixels, 1, in, mode_in); } else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGB) { getPixelColorsRGBA8(out, numpixels, 0, in, mode_in); } else { unsigned char r = 0, g = 0, b = 0, a = 0; for(i = 0; i != numpixels; ++i) { getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in); CERROR_TRY_RETURN(rgba8ToPixel(out, i, mode_out, &tree, r, g, b, a)); } } if(mode_out->colortype == LCT_PALETTE) { color_tree_cleanup(&tree); } return 0; /*no error*/ } #ifdef LODEPNG_COMPILE_ENCODER void lodepng_color_profile_init(LodePNGColorProfile* profile) { profile->colored = 0; profile->key = 0; profile->alpha = 0; profile->key_r = profile->key_g = profile->key_b = 0; profile->numcolors = 0; profile->bits = 1; } /*function used for debug purposes with C++*/ /*void printColorProfile(LodePNGColorProfile* p) { std::cout << "colored: " << (int)p->colored << ", "; std::cout << "key: " << (int)p->key << ", "; std::cout << "key_r: " << (int)p->key_r << ", "; std::cout << "key_g: " << (int)p->key_g << ", "; std::cout << "key_b: " << (int)p->key_b << ", "; std::cout << "alpha: " << (int)p->alpha << ", "; std::cout << "numcolors: " << (int)p->numcolors << ", "; std::cout << "bits: " << (int)p->bits << std::endl; }*/ /*Returns how many bits needed to represent given value (max 8 bit)*/ static unsigned getValueRequiredBits(unsigned char value) { if(value == 0 || value == 255) return 1; /*The scaling of 2-bit and 4-bit values uses multiples of 85 and 17*/ if(value % 17 == 0) return value % 85 == 0 ? 2 : 4; return 8; } /*profile must already have been inited with mode. It's ok to set some parameters of profile to done already.*/ unsigned lodepng_get_color_profile(LodePNGColorProfile* profile, const unsigned char* in, unsigned w, unsigned h, const LodePNGColorMode* mode) { unsigned error = 0; size_t i; ColorTree tree; size_t numpixels = w * h; unsigned colored_done = lodepng_is_greyscale_type(mode) ? 1 : 0; unsigned alpha_done = lodepng_can_have_alpha(mode) ? 0 : 1; unsigned numcolors_done = 0; unsigned bpp = lodepng_get_bpp(mode); unsigned bits_done = bpp == 1 ? 1 : 0; unsigned maxnumcolors = 257; unsigned sixteen = 0; if(bpp <= 8) maxnumcolors = bpp == 1 ? 2 : (bpp == 2 ? 4 : (bpp == 4 ? 16 : 256)); color_tree_init(&tree); /*Check if the 16-bit input is truly 16-bit*/ if(mode->bitdepth == 16) { unsigned short r, g, b, a; for(i = 0; i != numpixels; ++i) { getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode); if((r & 255) != ((r >> 8) & 255) || (g & 255) != ((g >> 8) & 255) || (b & 255) != ((b >> 8) & 255) || (a & 255) != ((a >> 8) & 255)) /*first and second byte differ*/ { sixteen = 1; break; } } } if(sixteen) { unsigned short r = 0, g = 0, b = 0, a = 0; profile->bits = 16; bits_done = numcolors_done = 1; /*counting colors no longer useful, palette doesn't support 16-bit*/ for(i = 0; i != numpixels; ++i) { getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode); if(!colored_done && (r != g || r != b)) { profile->colored = 1; colored_done = 1; } if(!alpha_done) { unsigned matchkey = (r == profile->key_r && g == profile->key_g && b == profile->key_b); if(a != 65535 && (a != 0 || (profile->key && !matchkey))) { profile->alpha = 1; alpha_done = 1; if(profile->bits < 8) profile->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ } else if(a == 0 && !profile->alpha && !profile->key) { profile->key = 1; profile->key_r = r; profile->key_g = g; profile->key_b = b; } else if(a == 65535 && profile->key && matchkey) { /* Color key cannot be used if an opaque pixel also has that RGB color. */ profile->alpha = 1; alpha_done = 1; } } if(alpha_done && numcolors_done && colored_done && bits_done) break; } if(profile->key && !profile->alpha) { for(i = 0; i != numpixels; ++i) { getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode); if(a != 0 && r == profile->key_r && g == profile->key_g && b == profile->key_b) { /* Color key cannot be used if an opaque pixel also has that RGB color. */ profile->alpha = 1; alpha_done = 1; } } } } else /* < 16-bit */ { unsigned char r = 0, g = 0, b = 0, a = 0; for(i = 0; i != numpixels; ++i) { getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode); if(!bits_done && profile->bits < 8) { /*only r is checked, < 8 bits is only relevant for greyscale*/ unsigned bits = getValueRequiredBits(r); if(bits > profile->bits) profile->bits = bits; } bits_done = (profile->bits >= bpp); if(!colored_done && (r != g || r != b)) { profile->colored = 1; colored_done = 1; if(profile->bits < 8) profile->bits = 8; /*PNG has no colored modes with less than 8-bit per channel*/ } if(!alpha_done) { unsigned matchkey = (r == profile->key_r && g == profile->key_g && b == profile->key_b); if(a != 255 && (a != 0 || (profile->key && !matchkey))) { profile->alpha = 1; alpha_done = 1; if(profile->bits < 8) profile->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ } else if(a == 0 && !profile->alpha && !profile->key) { profile->key = 1; profile->key_r = r; profile->key_g = g; profile->key_b = b; } else if(a == 255 && profile->key && matchkey) { /* Color key cannot be used if an opaque pixel also has that RGB color. */ profile->alpha = 1; alpha_done = 1; if(profile->bits < 8) profile->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ } } if(!numcolors_done) { if(!color_tree_has(&tree, r, g, b, a)) { color_tree_add(&tree, r, g, b, a, profile->numcolors); if(profile->numcolors < 256) { unsigned char* p = profile->palette; unsigned n = profile->numcolors; p[n * 4 + 0] = r; p[n * 4 + 1] = g; p[n * 4 + 2] = b; p[n * 4 + 3] = a; } ++profile->numcolors; numcolors_done = profile->numcolors >= maxnumcolors; } } if(alpha_done && numcolors_done && colored_done && bits_done) break; } if(profile->key && !profile->alpha) { for(i = 0; i != numpixels; ++i) { getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode); if(a != 0 && r == profile->key_r && g == profile->key_g && b == profile->key_b) { /* Color key cannot be used if an opaque pixel also has that RGB color. */ profile->alpha = 1; alpha_done = 1; } } } /*make the profile's key always 16-bit for consistency - repeat each byte twice*/ profile->key_r += (profile->key_r << 8); profile->key_g += (profile->key_g << 8); profile->key_b += (profile->key_b << 8); } color_tree_cleanup(&tree); return error; } /*Automatically chooses color type that gives smallest amount of bits in the output image, e.g. grey if there are only greyscale pixels, palette if there are less than 256 colors, ... Updates values of mode with a potentially smaller color model. mode_out should contain the user chosen color model, but will be overwritten with the new chosen one.*/ unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out, const unsigned char* image, unsigned w, unsigned h, const LodePNGColorMode* mode_in) { LodePNGColorProfile prof; unsigned error = 0; unsigned i, n, palettebits, grey_ok, palette_ok; lodepng_color_profile_init(&prof); error = lodepng_get_color_profile(&prof, image, w, h, mode_in); if(error) return error; mode_out->key_defined = 0; if(prof.key && w * h <= 16) { prof.alpha = 1; /*too few pixels to justify tRNS chunk overhead*/ if(prof.bits < 8) prof.bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ } grey_ok = !prof.colored && !prof.alpha; /*grey without alpha, with potentially low bits*/ n = prof.numcolors; palettebits = n <= 2 ? 1 : (n <= 4 ? 2 : (n <= 16 ? 4 : 8)); palette_ok = n <= 256 && (n * 2 < w * h) && prof.bits <= 8; if(w * h < n * 2) palette_ok = 0; /*don't add palette overhead if image has only a few pixels*/ if(grey_ok && prof.bits <= palettebits) palette_ok = 0; /*grey is less overhead*/ if(palette_ok) { unsigned char* p = prof.palette; lodepng_palette_clear(mode_out); /*remove potential earlier palette*/ for(i = 0; i != prof.numcolors; ++i) { error = lodepng_palette_add(mode_out, p[i * 4 + 0], p[i * 4 + 1], p[i * 4 + 2], p[i * 4 + 3]); if(error) break; } mode_out->colortype = LCT_PALETTE; mode_out->bitdepth = palettebits; if(mode_in->colortype == LCT_PALETTE && mode_in->palettesize >= mode_out->palettesize && mode_in->bitdepth == mode_out->bitdepth) { /*If input should have same palette colors, keep original to preserve its order and prevent conversion*/ lodepng_color_mode_cleanup(mode_out); lodepng_color_mode_copy(mode_out, mode_in); } } else /*8-bit or 16-bit per channel*/ { mode_out->bitdepth = prof.bits; mode_out->colortype = prof.alpha ? (prof.colored ? LCT_RGBA : LCT_GREY_ALPHA) : (prof.colored ? LCT_RGB : LCT_GREY); if(prof.key && !prof.alpha) { unsigned mask = (1u << mode_out->bitdepth) - 1u; /*profile always uses 16-bit, mask converts it*/ mode_out->key_r = prof.key_r & mask; mode_out->key_g = prof.key_g & mask; mode_out->key_b = prof.key_b & mask; mode_out->key_defined = 1; } } return error; } #endif /* #ifdef LODEPNG_COMPILE_ENCODER */ /* Paeth predicter, used by PNG filter type 4 The parameters are of type short, but should come from unsigned chars, the shorts are only needed to make the paeth calculation correct. */ static unsigned char paethPredictor(short a, short b, short c) { short pa = abs(b - c); short pb = abs(a - c); short pc = abs(a + b - c - c); if(pc < pa && pc < pb) return (unsigned char)c; else if(pb < pa) return (unsigned char)b; else return (unsigned char)a; } /*shared values used by multiple Adam7 related functions*/ static const unsigned ADAM7_IX[7] = { 0, 4, 0, 2, 0, 1, 0 }; /*x start values*/ static const unsigned ADAM7_IY[7] = { 0, 0, 4, 0, 2, 0, 1 }; /*y start values*/ static const unsigned ADAM7_DX[7] = { 8, 8, 4, 4, 2, 2, 1 }; /*x delta values*/ static const unsigned ADAM7_DY[7] = { 8, 8, 8, 4, 4, 2, 2 }; /*y delta values*/ /* Outputs various dimensions and positions in the image related to the Adam7 reduced images. passw: output containing the width of the 7 passes passh: output containing the height of the 7 passes filter_passstart: output containing the index of the start and end of each reduced image with filter bytes padded_passstart output containing the index of the start and end of each reduced image when without filter bytes but with padded scanlines passstart: output containing the index of the start and end of each reduced image without padding between scanlines, but still padding between the images w, h: width and height of non-interlaced image bpp: bits per pixel "padded" is only relevant if bpp is less than 8 and a scanline or image does not end at a full byte */ static void Adam7_getpassvalues(unsigned passw[7], unsigned passh[7], size_t filter_passstart[8], size_t padded_passstart[8], size_t passstart[8], unsigned w, unsigned h, unsigned bpp) { /*the passstart values have 8 values: the 8th one indicates the byte after the end of the 7th (= last) pass*/ unsigned i; /*calculate width and height in pixels of each pass*/ for(i = 0; i != 7; ++i) { passw[i] = (w + ADAM7_DX[i] - ADAM7_IX[i] - 1) / ADAM7_DX[i]; passh[i] = (h + ADAM7_DY[i] - ADAM7_IY[i] - 1) / ADAM7_DY[i]; if(passw[i] == 0) passh[i] = 0; if(passh[i] == 0) passw[i] = 0; } filter_passstart[0] = padded_passstart[0] = passstart[0] = 0; for(i = 0; i != 7; ++i) { /*if passw[i] is 0, it's 0 bytes, not 1 (no filtertype-byte)*/ filter_passstart[i + 1] = filter_passstart[i] + ((passw[i] && passh[i]) ? passh[i] * (1 + (passw[i] * bpp + 7) / 8) : 0); /*bits padded if needed to fill full byte at end of each scanline*/ padded_passstart[i + 1] = padded_passstart[i] + passh[i] * ((passw[i] * bpp + 7) / 8); /*only padded at end of reduced image*/ passstart[i + 1] = passstart[i] + (passh[i] * passw[i] * bpp + 7) / 8; } } #ifdef LODEPNG_COMPILE_DECODER /* ////////////////////////////////////////////////////////////////////////// */ /* / PNG Decoder / */ /* ////////////////////////////////////////////////////////////////////////// */ /*read the information from the header and store it in the LodePNGInfo. return value is error*/ unsigned lodepng_inspect(unsigned* w, unsigned* h, LodePNGState* state, const unsigned char* in, size_t insize) { LodePNGInfo* info = &state->info_png; if(insize == 0 || in == 0) { CERROR_RETURN_ERROR(state->error, 48); /*error: the given data is empty*/ } if(insize < 33) { CERROR_RETURN_ERROR(state->error, 27); /*error: the data length is smaller than the length of a PNG header*/ } /*when decoding a new PNG image, make sure all parameters created after previous decoding are reset*/ lodepng_info_cleanup(info); lodepng_info_init(info); if(in[0] != 137 || in[1] != 80 || in[2] != 78 || in[3] != 71 || in[4] != 13 || in[5] != 10 || in[6] != 26 || in[7] != 10) { CERROR_RETURN_ERROR(state->error, 28); /*error: the first 8 bytes are not the correct PNG signature*/ } if(lodepng_chunk_length(in + 8) != 13) { CERROR_RETURN_ERROR(state->error, 94); /*error: header size must be 13 bytes*/ } if(!lodepng_chunk_type_equals(in + 8, "IHDR")) { CERROR_RETURN_ERROR(state->error, 29); /*error: it doesn't start with a IHDR chunk!*/ } /*read the values given in the header*/ *w = lodepng_read32bitInt(&in[16]); *h = lodepng_read32bitInt(&in[20]); info->color.bitdepth = in[24]; info->color.colortype = (LodePNGColorType)in[25]; info->compression_method = in[26]; info->filter_method = in[27]; info->interlace_method = in[28]; if(*w == 0 || *h == 0) { CERROR_RETURN_ERROR(state->error, 93); } if(!state->decoder.ignore_crc) { unsigned CRC = lodepng_read32bitInt(&in[29]); unsigned checksum = lodepng_crc32(&in[12], 17); if(CRC != checksum) { CERROR_RETURN_ERROR(state->error, 57); /*invalid CRC*/ } } /*error: only compression method 0 is allowed in the specification*/ if(info->compression_method != 0) CERROR_RETURN_ERROR(state->error, 32); /*error: only filter method 0 is allowed in the specification*/ if(info->filter_method != 0) CERROR_RETURN_ERROR(state->error, 33); /*error: only interlace methods 0 and 1 exist in the specification*/ if(info->interlace_method > 1) CERROR_RETURN_ERROR(state->error, 34); state->error = checkColorValidity(info->color.colortype, info->color.bitdepth); return state->error; } static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scanline, const unsigned char* precon, size_t bytewidth, unsigned char filterType, size_t length) { /* For PNG filter method 0 unfilter a PNG image scanline by scanline. when the pixels are smaller than 1 byte, the filter works byte per byte (bytewidth = 1) precon is the previous unfiltered scanline, recon the result, scanline the current one the incoming scanlines do NOT include the filtertype byte, that one is given in the parameter filterType instead recon and scanline MAY be the same memory address! precon must be disjoint. */ size_t i; switch(filterType) { case 0: for(i = 0; i != length; ++i) recon[i] = scanline[i]; break; case 1: for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i]; for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + recon[i - bytewidth]; break; case 2: if(precon) { for(i = 0; i != length; ++i) recon[i] = scanline[i] + precon[i]; } else { for(i = 0; i != length; ++i) recon[i] = scanline[i]; } break; case 3: if(precon) { for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i] + (precon[i] >> 1); for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) >> 1); } else { for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i]; for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + (recon[i - bytewidth] >> 1); } break; case 4: if(precon) { for(i = 0; i != bytewidth; ++i) { recon[i] = (scanline[i] + precon[i]); /*paethPredictor(0, precon[i], 0) is always precon[i]*/ } for(i = bytewidth; i < length; ++i) { recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth])); } } else { for(i = 0; i != bytewidth; ++i) { recon[i] = scanline[i]; } for(i = bytewidth; i < length; ++i) { /*paethPredictor(recon[i - bytewidth], 0, 0) is always recon[i - bytewidth]*/ recon[i] = (scanline[i] + recon[i - bytewidth]); } } break; default: return 36; /*error: unexisting filter type given*/ } return 0; } static unsigned unfilter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) { /* For PNG filter method 0 this function unfilters a single image (e.g. without interlacing this is called once, with Adam7 seven times) out must have enough bytes allocated already, in must have the scanlines + 1 filtertype byte per scanline w and h are image dimensions or dimensions of reduced image, bpp is bits per pixel in and out are allowed to be the same memory address (but aren't the same size since in has the extra filter bytes) */ unsigned y; unsigned char* prevline = 0; /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/ size_t bytewidth = (bpp + 7) / 8; size_t linebytes = (w * bpp + 7) / 8; for(y = 0; y < h; ++y) { size_t outindex = linebytes * y; size_t inindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ unsigned char filterType = in[inindex]; CERROR_TRY_RETURN(unfilterScanline(&out[outindex], &in[inindex + 1], prevline, bytewidth, filterType, linebytes)); prevline = &out[outindex]; } return 0; } /* in: Adam7 interlaced image, with no padding bits between scanlines, but between reduced images so that each reduced image starts at a byte. out: the same pixels, but re-ordered so that they're now a non-interlaced image with size w*h bpp: bits per pixel out has the following size in bits: w * h * bpp. in is possibly bigger due to padding bits between reduced images. out must be big enough AND must be 0 everywhere if bpp < 8 in the current implementation (because that's likely a little bit faster) NOTE: comments about padding bits are only relevant if bpp < 8 */ static void Adam7_deinterlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) { unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8]; unsigned i; Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); if(bpp >= 8) { for(i = 0; i != 7; ++i) { unsigned x, y, b; size_t bytewidth = bpp / 8; for(y = 0; y < passh[i]; ++y) for(x = 0; x < passw[i]; ++x) { size_t pixelinstart = passstart[i] + (y * passw[i] + x) * bytewidth; size_t pixeloutstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth; for(b = 0; b < bytewidth; ++b) { out[pixeloutstart + b] = in[pixelinstart + b]; } } } } else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/ { for(i = 0; i != 7; ++i) { unsigned x, y, b; unsigned ilinebits = bpp * passw[i]; unsigned olinebits = bpp * w; size_t obp, ibp; /*bit pointers (for out and in buffer)*/ for(y = 0; y < passh[i]; ++y) for(x = 0; x < passw[i]; ++x) { ibp = (8 * passstart[i]) + (y * ilinebits + x * bpp); obp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp; for(b = 0; b < bpp; ++b) { unsigned char bit = readBitFromReversedStream(&ibp, in); /*note that this function assumes the out buffer is completely 0, use setBitOfReversedStream otherwise*/ setBitOfReversedStream0(&obp, out, bit); } } } } } static void removePaddingBits(unsigned char* out, const unsigned char* in, size_t olinebits, size_t ilinebits, unsigned h) { /* After filtering there are still padding bits if scanlines have non multiple of 8 bit amounts. They need to be removed (except at last scanline of (Adam7-reduced) image) before working with pure image buffers for the Adam7 code, the color convert code and the output to the user. in and out are allowed to be the same buffer, in may also be higher but still overlapping; in must have >= ilinebits*h bits, out must have >= olinebits*h bits, olinebits must be <= ilinebits also used to move bits after earlier such operations happened, e.g. in a sequence of reduced images from Adam7 only useful if (ilinebits - olinebits) is a value in the range 1..7 */ unsigned y; size_t diff = ilinebits - olinebits; size_t ibp = 0, obp = 0; /*input and output bit pointers*/ for(y = 0; y < h; ++y) { size_t x; for(x = 0; x < olinebits; ++x) { unsigned char bit = readBitFromReversedStream(&ibp, in); setBitOfReversedStream(&obp, out, bit); } ibp += diff; } } /*out must be buffer big enough to contain full image, and in must contain the full decompressed data from the IDAT chunks (with filter index bytes and possible padding bits) return value is error*/ static unsigned postProcessScanlines(unsigned char* out, unsigned char* in, unsigned w, unsigned h, const LodePNGInfo* info_png) { /* This function converts the filtered-padded-interlaced data into pure 2D image buffer with the PNG's colortype. Steps: *) if no Adam7: 1) unfilter 2) remove padding bits (= posible extra bits per scanline if bpp < 8) *) if adam7: 1) 7x unfilter 2) 7x remove padding bits 3) Adam7_deinterlace NOTE: the in buffer will be overwritten with intermediate data! */ unsigned bpp = lodepng_get_bpp(&info_png->color); if(bpp == 0) return 31; /*error: invalid colortype*/ if(info_png->interlace_method == 0) { if(bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8) { CERROR_TRY_RETURN(unfilter(in, in, w, h, bpp)); removePaddingBits(out, in, w * bpp, ((w * bpp + 7) / 8) * 8, h); } /*we can immediately filter into the out buffer, no other steps needed*/ else CERROR_TRY_RETURN(unfilter(out, in, w, h, bpp)); } else /*interlace_method is 1 (Adam7)*/ { unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8]; unsigned i; Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); for(i = 0; i != 7; ++i) { CERROR_TRY_RETURN(unfilter(&in[padded_passstart[i]], &in[filter_passstart[i]], passw[i], passh[i], bpp)); /*TODO: possible efficiency improvement: if in this reduced image the bits fit nicely in 1 scanline, move bytes instead of bits or move not at all*/ if(bpp < 8) { /*remove padding bits in scanlines; after this there still may be padding bits between the different reduced images: each reduced image still starts nicely at a byte*/ removePaddingBits(&in[passstart[i]], &in[padded_passstart[i]], passw[i] * bpp, ((passw[i] * bpp + 7) / 8) * 8, passh[i]); } } Adam7_deinterlace(out, in, w, h, bpp); } return 0; } static unsigned readChunk_PLTE(LodePNGColorMode* color, const unsigned char* data, size_t chunkLength) { unsigned pos = 0, i; if(color->palette) lodepng_free(color->palette); color->palettesize = chunkLength / 3; color->palette = (unsigned char*)lodepng_malloc(4 * color->palettesize); if(!color->palette && color->palettesize) { color->palettesize = 0; return 83; /*alloc fail*/ } if(color->palettesize > 256) return 38; /*error: palette too big*/ for(i = 0; i != color->palettesize; ++i) { color->palette[4 * i + 0] = data[pos++]; /*R*/ color->palette[4 * i + 1] = data[pos++]; /*G*/ color->palette[4 * i + 2] = data[pos++]; /*B*/ color->palette[4 * i + 3] = 255; /*alpha*/ } return 0; /* OK */ } static unsigned readChunk_tRNS(LodePNGColorMode* color, const unsigned char* data, size_t chunkLength) { unsigned i; if(color->colortype == LCT_PALETTE) { /*error: more alpha values given than there are palette entries*/ if(chunkLength > color->palettesize) return 38; for(i = 0; i != chunkLength; ++i) color->palette[4 * i + 3] = data[i]; } else if(color->colortype == LCT_GREY) { /*error: this chunk must be 2 bytes for greyscale image*/ if(chunkLength != 2) return 30; color->key_defined = 1; color->key_r = color->key_g = color->key_b = 256u * data[0] + data[1]; } else if(color->colortype == LCT_RGB) { /*error: this chunk must be 6 bytes for RGB image*/ if(chunkLength != 6) return 41; color->key_defined = 1; color->key_r = 256u * data[0] + data[1]; color->key_g = 256u * data[2] + data[3]; color->key_b = 256u * data[4] + data[5]; } else return 42; /*error: tRNS chunk not allowed for other color models*/ return 0; /* OK */ } #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /*background color chunk (bKGD)*/ static unsigned readChunk_bKGD(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { if(info->color.colortype == LCT_PALETTE) { /*error: this chunk must be 1 byte for indexed color image*/ if(chunkLength != 1) return 43; info->background_defined = 1; info->background_r = info->background_g = info->background_b = data[0]; } else if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA) { /*error: this chunk must be 2 bytes for greyscale image*/ if(chunkLength != 2) return 44; info->background_defined = 1; info->background_r = info->background_g = info->background_b = 256u * data[0] + data[1]; } else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA) { /*error: this chunk must be 6 bytes for greyscale image*/ if(chunkLength != 6) return 45; info->background_defined = 1; info->background_r = 256u * data[0] + data[1]; info->background_g = 256u * data[2] + data[3]; info->background_b = 256u * data[4] + data[5]; } return 0; /* OK */ } /*text chunk (tEXt)*/ static unsigned readChunk_tEXt(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { unsigned error = 0; char *key = 0, *str = 0; unsigned i; while(!error) /*not really a while loop, only used to break on error*/ { unsigned length, string2_begin; length = 0; while(length < chunkLength && data[length] != 0) ++length; /*even though it's not allowed by the standard, no error is thrown if there's no null termination char, if the text is empty*/ if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ key = (char*)lodepng_malloc(length + 1); if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ key[length] = 0; for(i = 0; i != length; ++i) key[i] = (char)data[i]; string2_begin = length + 1; /*skip keyword null terminator*/ length = chunkLength < string2_begin ? 0 : chunkLength - string2_begin; str = (char*)lodepng_malloc(length + 1); if(!str) CERROR_BREAK(error, 83); /*alloc fail*/ str[length] = 0; for(i = 0; i != length; ++i) str[i] = (char)data[string2_begin + i]; error = lodepng_add_text(info, key, str); break; } lodepng_free(key); lodepng_free(str); return error; } /*compressed text chunk (zTXt)*/ static unsigned readChunk_zTXt(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings, const unsigned char* data, size_t chunkLength) { unsigned error = 0; unsigned i; unsigned length, string2_begin; char *key = 0; ucvector decoded; ucvector_init(&decoded); while(!error) /*not really a while loop, only used to break on error*/ { for(length = 0; length < chunkLength && data[length] != 0; ++length) ; if(length + 2 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/ if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ key = (char*)lodepng_malloc(length + 1); if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ key[length] = 0; for(i = 0; i != length; ++i) key[i] = (char)data[i]; if(data[length + 1] != 0) CERROR_BREAK(error, 72); /*the 0 byte indicating compression must be 0*/ string2_begin = length + 2; if(string2_begin > chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/ length = chunkLength - string2_begin; /*will fail if zlib error, e.g. if length is too small*/ error = zlib_decompress(&decoded.data, &decoded.size, (unsigned char*)(&data[string2_begin]), length, zlibsettings); if(error) break; ucvector_push_back(&decoded, 0); error = lodepng_add_text(info, key, (char*)decoded.data); break; } lodepng_free(key); ucvector_cleanup(&decoded); return error; } /*international text chunk (iTXt)*/ static unsigned readChunk_iTXt(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings, const unsigned char* data, size_t chunkLength) { unsigned error = 0; unsigned i; unsigned length, begin, compressed; char *key = 0, *langtag = 0, *transkey = 0; ucvector decoded; ucvector_init(&decoded); while(!error) /*not really a while loop, only used to break on error*/ { /*Quick check if the chunk length isn't too small. Even without check it'd still fail with other error checks below if it's too short. This just gives a different error code.*/ if(chunkLength < 5) CERROR_BREAK(error, 30); /*iTXt chunk too short*/ /*read the key*/ for(length = 0; length < chunkLength && data[length] != 0; ++length) ; if(length + 3 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination char, corrupt?*/ if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ key = (char*)lodepng_malloc(length + 1); if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ key[length] = 0; for(i = 0; i != length; ++i) key[i] = (char)data[i]; /*read the compression method*/ compressed = data[length + 1]; if(data[length + 2] != 0) CERROR_BREAK(error, 72); /*the 0 byte indicating compression must be 0*/ /*even though it's not allowed by the standard, no error is thrown if there's no null termination char, if the text is empty for the next 3 texts*/ /*read the langtag*/ begin = length + 3; length = 0; for(i = begin; i < chunkLength && data[i] != 0; ++i) ++length; langtag = (char*)lodepng_malloc(length + 1); if(!langtag) CERROR_BREAK(error, 83); /*alloc fail*/ langtag[length] = 0; for(i = 0; i != length; ++i) langtag[i] = (char)data[begin + i]; /*read the transkey*/ begin += length + 1; length = 0; for(i = begin; i < chunkLength && data[i] != 0; ++i) ++length; transkey = (char*)lodepng_malloc(length + 1); if(!transkey) CERROR_BREAK(error, 83); /*alloc fail*/ transkey[length] = 0; for(i = 0; i != length; ++i) transkey[i] = (char)data[begin + i]; /*read the actual text*/ begin += length + 1; length = chunkLength < begin ? 0 : chunkLength - begin; if(compressed) { /*will fail if zlib error, e.g. if length is too small*/ error = zlib_decompress(&decoded.data, &decoded.size, (unsigned char*)(&data[begin]), length, zlibsettings); if(error) break; if(decoded.allocsize < decoded.size) decoded.allocsize = decoded.size; ucvector_push_back(&decoded, 0); } else { if(!ucvector_resize(&decoded, length + 1)) CERROR_BREAK(error, 83 /*alloc fail*/); decoded.data[length] = 0; for(i = 0; i != length; ++i) decoded.data[i] = data[begin + i]; } error = lodepng_add_itext(info, key, langtag, transkey, (char*)decoded.data); break; } lodepng_free(key); lodepng_free(langtag); lodepng_free(transkey); ucvector_cleanup(&decoded); return error; } static unsigned readChunk_tIME(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { if(chunkLength != 7) return 73; /*invalid tIME chunk size*/ info->time_defined = 1; info->time.year = 256u * data[0] + data[1]; info->time.month = data[2]; info->time.day = data[3]; info->time.hour = data[4]; info->time.minute = data[5]; info->time.second = data[6]; return 0; /* OK */ } static unsigned readChunk_pHYs(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { if(chunkLength != 9) return 74; /*invalid pHYs chunk size*/ info->phys_defined = 1; info->phys_x = 16777216u * data[0] + 65536u * data[1] + 256u * data[2] + data[3]; info->phys_y = 16777216u * data[4] + 65536u * data[5] + 256u * data[6] + data[7]; info->phys_unit = data[8]; return 0; /* OK */ } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ /*read a PNG, the result will be in the same color type as the PNG (hence "generic")*/ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h, LodePNGState* state, const unsigned char* in, size_t insize) { unsigned char IEND = 0; const unsigned char* chunk; size_t i; ucvector idat; /*the data from idat chunks*/ ucvector scanlines; size_t predict; size_t numpixels; size_t outsize = 0; /*for unknown chunk order*/ unsigned unknown = 0; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS unsigned critical_pos = 1; /*1 = after IHDR, 2 = after PLTE, 3 = after IDAT*/ #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ /*provide some proper output values if error will happen*/ *out = 0; state->error = lodepng_inspect(w, h, state, in, insize); /*reads header and resets other parameters in state->info_png*/ if(state->error) return; numpixels = *w * *h; /*multiplication overflow*/ if(*h != 0 && numpixels / *h != *w) CERROR_RETURN(state->error, 92); /*multiplication overflow possible further below. Allows up to 2^31-1 pixel bytes with 16-bit RGBA, the rest is room for filter bytes.*/ if(numpixels > 268435455) CERROR_RETURN(state->error, 92); ucvector_init(&idat); chunk = &in[33]; /*first byte of the first chunk after the header*/ /*loop through the chunks, ignoring unknown chunks and stopping at IEND chunk. IDAT data is put at the start of the in buffer*/ while(!IEND && !state->error) { unsigned chunkLength; const unsigned char* data; /*the data in the chunk*/ /*error: size of the in buffer too small to contain next chunk*/ if((size_t)((chunk - in) + 12) > insize || chunk < in) CERROR_BREAK(state->error, 30); /*length of the data of the chunk, excluding the length bytes, chunk type and CRC bytes*/ chunkLength = lodepng_chunk_length(chunk); /*error: chunk length larger than the max PNG chunk size*/ if(chunkLength > 2147483647) CERROR_BREAK(state->error, 63); if((size_t)((chunk - in) + chunkLength + 12) > insize || (chunk + chunkLength + 12) < in) { CERROR_BREAK(state->error, 64); /*error: size of the in buffer too small to contain next chunk*/ } data = lodepng_chunk_data_const(chunk); /*IDAT chunk, containing compressed image data*/ if(lodepng_chunk_type_equals(chunk, "IDAT")) { size_t oldsize = idat.size; if(!ucvector_resize(&idat, oldsize + chunkLength)) CERROR_BREAK(state->error, 83 /*alloc fail*/); for(i = 0; i != chunkLength; ++i) idat.data[oldsize + i] = data[i]; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS critical_pos = 3; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } /*IEND chunk*/ else if(lodepng_chunk_type_equals(chunk, "IEND")) { IEND = 1; } /*palette chunk (PLTE)*/ else if(lodepng_chunk_type_equals(chunk, "PLTE")) { state->error = readChunk_PLTE(&state->info_png.color, data, chunkLength); if(state->error) break; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS critical_pos = 2; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } /*palette transparency chunk (tRNS)*/ else if(lodepng_chunk_type_equals(chunk, "tRNS")) { state->error = readChunk_tRNS(&state->info_png.color, data, chunkLength); if(state->error) break; } #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /*background color chunk (bKGD)*/ else if(lodepng_chunk_type_equals(chunk, "bKGD")) { state->error = readChunk_bKGD(&state->info_png, data, chunkLength); if(state->error) break; } /*text chunk (tEXt)*/ else if(lodepng_chunk_type_equals(chunk, "tEXt")) { if(state->decoder.read_text_chunks) { state->error = readChunk_tEXt(&state->info_png, data, chunkLength); if(state->error) break; } } /*compressed text chunk (zTXt)*/ else if(lodepng_chunk_type_equals(chunk, "zTXt")) { if(state->decoder.read_text_chunks) { state->error = readChunk_zTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength); if(state->error) break; } } /*international text chunk (iTXt)*/ else if(lodepng_chunk_type_equals(chunk, "iTXt")) { if(state->decoder.read_text_chunks) { state->error = readChunk_iTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength); if(state->error) break; } } else if(lodepng_chunk_type_equals(chunk, "tIME")) { state->error = readChunk_tIME(&state->info_png, data, chunkLength); if(state->error) break; } else if(lodepng_chunk_type_equals(chunk, "pHYs")) { state->error = readChunk_pHYs(&state->info_png, data, chunkLength); if(state->error) break; } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ else /*it's not an implemented chunk type, so ignore it: skip over the data*/ { /*error: unknown critical chunk (5th bit of first byte of chunk type is 0)*/ if(!lodepng_chunk_ancillary(chunk)) CERROR_BREAK(state->error, 69); unknown = 1; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS if(state->decoder.remember_unknown_chunks) { state->error = lodepng_chunk_append(&state->info_png.unknown_chunks_data[critical_pos - 1], &state->info_png.unknown_chunks_size[critical_pos - 1], chunk); if(state->error) break; } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } if(!state->decoder.ignore_crc && !unknown) /*check CRC if wanted, only on known chunk types*/ { if(lodepng_chunk_check_crc(chunk)) CERROR_BREAK(state->error, 57); /*invalid CRC*/ } if(!IEND) chunk = lodepng_chunk_next_const(chunk); } ucvector_init(&scanlines); /*predict output size, to allocate exact size for output buffer to avoid more dynamic allocation. If the decompressed size does not match the prediction, the image must be corrupt.*/ if(state->info_png.interlace_method == 0) { /*The extra *h is added because this are the filter bytes every scanline starts with*/ predict = lodepng_get_raw_size_idat(*w, *h, &state->info_png.color) + *h; } else { /*Adam-7 interlaced: predicted size is the sum of the 7 sub-images sizes*/ const LodePNGColorMode* color = &state->info_png.color; predict = 0; predict += lodepng_get_raw_size_idat((*w + 7) >> 3, (*h + 7) >> 3, color) + ((*h + 7) >> 3); if(*w > 4) predict += lodepng_get_raw_size_idat((*w + 3) >> 3, (*h + 7) >> 3, color) + ((*h + 7) >> 3); predict += lodepng_get_raw_size_idat((*w + 3) >> 2, (*h + 3) >> 3, color) + ((*h + 3) >> 3); if(*w > 2) predict += lodepng_get_raw_size_idat((*w + 1) >> 2, (*h + 3) >> 2, color) + ((*h + 3) >> 2); predict += lodepng_get_raw_size_idat((*w + 1) >> 1, (*h + 1) >> 2, color) + ((*h + 1) >> 2); if(*w > 1) predict += lodepng_get_raw_size_idat((*w + 0) >> 1, (*h + 1) >> 1, color) + ((*h + 1) >> 1); predict += lodepng_get_raw_size_idat((*w + 0), (*h + 0) >> 1, color) + ((*h + 0) >> 1); } if(!state->error && !ucvector_reserve(&scanlines, predict)) state->error = 83; /*alloc fail*/ if(!state->error) { state->error = zlib_decompress(&scanlines.data, &scanlines.size, idat.data, idat.size, &state->decoder.zlibsettings); if(!state->error && scanlines.size != predict) state->error = 91; /*decompressed size doesn't match prediction*/ } ucvector_cleanup(&idat); if(!state->error) { outsize = lodepng_get_raw_size(*w, *h, &state->info_png.color); *out = (unsigned char*)lodepng_malloc(outsize); if(!*out) state->error = 83; /*alloc fail*/ } if(!state->error) { for(i = 0; i < outsize; i++) (*out)[i] = 0; state->error = postProcessScanlines(*out, scanlines.data, *w, *h, &state->info_png); } ucvector_cleanup(&scanlines); } unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h, LodePNGState* state, const unsigned char* in, size_t insize) { *out = 0; decodeGeneric(out, w, h, state, in, insize); if(state->error) return state->error; if(!state->decoder.color_convert || lodepng_color_mode_equal(&state->info_raw, &state->info_png.color)) { /*same color type, no copying or converting of data needed*/ /*store the info_png color settings on the info_raw so that the info_raw still reflects what colortype the raw image has to the end user*/ if(!state->decoder.color_convert) { state->error = lodepng_color_mode_copy(&state->info_raw, &state->info_png.color); if(state->error) return state->error; } } else { /*color conversion needed; sort of copy of the data*/ unsigned char* data = *out; size_t outsize; /*TODO: check if this works according to the statement in the documentation: "The converter can convert from greyscale input color type, to 8-bit greyscale or greyscale with alpha"*/ if(!(state->info_raw.colortype == LCT_RGB || state->info_raw.colortype == LCT_RGBA) && !(state->info_raw.bitdepth == 8)) { return 56; /*unsupported color mode conversion*/ } outsize = lodepng_get_raw_size(*w, *h, &state->info_raw); *out = (unsigned char*)lodepng_malloc(outsize); if(!(*out)) { state->error = 83; /*alloc fail*/ } else state->error = lodepng_convert(*out, data, &state->info_raw, &state->info_png.color, *w, *h); lodepng_free(data); } return state->error; } unsigned lodepng_decode_memory(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize, LodePNGColorType colortype, unsigned bitdepth) { unsigned error; LodePNGState state; lodepng_state_init(&state); state.info_raw.colortype = colortype; state.info_raw.bitdepth = bitdepth; error = lodepng_decode(out, w, h, &state, in, insize); lodepng_state_cleanup(&state); return error; } unsigned lodepng_decode32(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize) { return lodepng_decode_memory(out, w, h, in, insize, LCT_RGBA, 8); } unsigned lodepng_decode24(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize) { return lodepng_decode_memory(out, w, h, in, insize, LCT_RGB, 8); } #ifdef LODEPNG_COMPILE_DISK unsigned lodepng_decode_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename, LodePNGColorType colortype, unsigned bitdepth) { unsigned char* buffer = 0; size_t buffersize; unsigned error; error = lodepng_load_file(&buffer, &buffersize, filename); if(!error) error = lodepng_decode_memory(out, w, h, buffer, buffersize, colortype, bitdepth); lodepng_free(buffer); return error; } unsigned lodepng_decode32_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename) { return lodepng_decode_file(out, w, h, filename, LCT_RGBA, 8); } unsigned lodepng_decode24_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename) { return lodepng_decode_file(out, w, h, filename, LCT_RGB, 8); } #endif /*LODEPNG_COMPILE_DISK*/ void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings) { settings->color_convert = 1; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS settings->read_text_chunks = 1; settings->remember_unknown_chunks = 0; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ settings->ignore_crc = 0; lodepng_decompress_settings_init(&settings->zlibsettings); } #endif /*LODEPNG_COMPILE_DECODER*/ #if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) void lodepng_state_init(LodePNGState* state) { #ifdef LODEPNG_COMPILE_DECODER lodepng_decoder_settings_init(&state->decoder); #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER lodepng_encoder_settings_init(&state->encoder); #endif /*LODEPNG_COMPILE_ENCODER*/ lodepng_color_mode_init(&state->info_raw); lodepng_info_init(&state->info_png); state->error = 1; } void lodepng_state_cleanup(LodePNGState* state) { lodepng_color_mode_cleanup(&state->info_raw); lodepng_info_cleanup(&state->info_png); } void lodepng_state_copy(LodePNGState* dest, const LodePNGState* source) { lodepng_state_cleanup(dest); *dest = *source; lodepng_color_mode_init(&dest->info_raw); lodepng_info_init(&dest->info_png); dest->error = lodepng_color_mode_copy(&dest->info_raw, &source->info_raw); if(dest->error) return; dest->error = lodepng_info_copy(&dest->info_png, &source->info_png); if(dest->error) return; } #endif /* defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) */ #ifdef LODEPNG_COMPILE_ENCODER /* ////////////////////////////////////////////////////////////////////////// */ /* / PNG Encoder / */ /* ////////////////////////////////////////////////////////////////////////// */ /*chunkName must be string of 4 characters*/ static unsigned addChunk(ucvector* out, const char* chunkName, const unsigned char* data, size_t length) { CERROR_TRY_RETURN(lodepng_chunk_create(&out->data, &out->size, (unsigned)length, chunkName, data)); out->allocsize = out->size; /*fix the allocsize again*/ return 0; } static void writeSignature(ucvector* out) { /*8 bytes PNG signature, aka the magic bytes*/ ucvector_push_back(out, 137); ucvector_push_back(out, 80); ucvector_push_back(out, 78); ucvector_push_back(out, 71); ucvector_push_back(out, 13); ucvector_push_back(out, 10); ucvector_push_back(out, 26); ucvector_push_back(out, 10); } static unsigned addChunk_IHDR(ucvector* out, unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth, unsigned interlace_method) { unsigned error = 0; ucvector header; ucvector_init(&header); lodepng_add32bitInt(&header, w); /*width*/ lodepng_add32bitInt(&header, h); /*height*/ ucvector_push_back(&header, (unsigned char)bitdepth); /*bit depth*/ ucvector_push_back(&header, (unsigned char)colortype); /*color type*/ ucvector_push_back(&header, 0); /*compression method*/ ucvector_push_back(&header, 0); /*filter method*/ ucvector_push_back(&header, interlace_method); /*interlace method*/ error = addChunk(out, "IHDR", header.data, header.size); ucvector_cleanup(&header); return error; } static unsigned addChunk_PLTE(ucvector* out, const LodePNGColorMode* info) { unsigned error = 0; size_t i; ucvector PLTE; ucvector_init(&PLTE); for(i = 0; i != info->palettesize * 4; ++i) { /*add all channels except alpha channel*/ if(i % 4 != 3) ucvector_push_back(&PLTE, info->palette[i]); } error = addChunk(out, "PLTE", PLTE.data, PLTE.size); ucvector_cleanup(&PLTE); return error; } static unsigned addChunk_tRNS(ucvector* out, const LodePNGColorMode* info) { unsigned error = 0; size_t i; ucvector tRNS; ucvector_init(&tRNS); if(info->colortype == LCT_PALETTE) { size_t amount = info->palettesize; /*the tail of palette values that all have 255 as alpha, does not have to be encoded*/ for(i = info->palettesize; i != 0; --i) { if(info->palette[4 * (i - 1) + 3] == 255) --amount; else break; } /*add only alpha channel*/ for(i = 0; i != amount; ++i) ucvector_push_back(&tRNS, info->palette[4 * i + 3]); } else if(info->colortype == LCT_GREY) { if(info->key_defined) { ucvector_push_back(&tRNS, (unsigned char)(info->key_r >> 8)); ucvector_push_back(&tRNS, (unsigned char)(info->key_r & 255)); } } else if(info->colortype == LCT_RGB) { if(info->key_defined) { ucvector_push_back(&tRNS, (unsigned char)(info->key_r >> 8)); ucvector_push_back(&tRNS, (unsigned char)(info->key_r & 255)); ucvector_push_back(&tRNS, (unsigned char)(info->key_g >> 8)); ucvector_push_back(&tRNS, (unsigned char)(info->key_g & 255)); ucvector_push_back(&tRNS, (unsigned char)(info->key_b >> 8)); ucvector_push_back(&tRNS, (unsigned char)(info->key_b & 255)); } } error = addChunk(out, "tRNS", tRNS.data, tRNS.size); ucvector_cleanup(&tRNS); return error; } static unsigned addChunk_IDAT(ucvector* out, const unsigned char* data, size_t datasize, LodePNGCompressSettings* zlibsettings) { ucvector zlibdata; unsigned error = 0; /*compress with the Zlib compressor*/ ucvector_init(&zlibdata); error = zlib_compress(&zlibdata.data, &zlibdata.size, data, datasize, zlibsettings); if(!error) error = addChunk(out, "IDAT", zlibdata.data, zlibdata.size); ucvector_cleanup(&zlibdata); return error; } static unsigned addChunk_IEND(ucvector* out) { unsigned error = 0; error = addChunk(out, "IEND", 0, 0); return error; } #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS static unsigned addChunk_tEXt(ucvector* out, const char* keyword, const char* textstring) { unsigned error = 0; size_t i; ucvector text; ucvector_init(&text); for(i = 0; keyword[i] != 0; ++i) ucvector_push_back(&text, (unsigned char)keyword[i]); if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/ ucvector_push_back(&text, 0); /*0 termination char*/ for(i = 0; textstring[i] != 0; ++i) ucvector_push_back(&text, (unsigned char)textstring[i]); error = addChunk(out, "tEXt", text.data, text.size); ucvector_cleanup(&text); return error; } static unsigned addChunk_zTXt(ucvector* out, const char* keyword, const char* textstring, LodePNGCompressSettings* zlibsettings) { unsigned error = 0; ucvector data, compressed; size_t i, textsize = strlen(textstring); ucvector_init(&data); ucvector_init(&compressed); for(i = 0; keyword[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)keyword[i]); if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/ ucvector_push_back(&data, 0); /*0 termination char*/ ucvector_push_back(&data, 0); /*compression method: 0*/ error = zlib_compress(&compressed.data, &compressed.size, (unsigned char*)textstring, textsize, zlibsettings); if(!error) { for(i = 0; i != compressed.size; ++i) ucvector_push_back(&data, compressed.data[i]); error = addChunk(out, "zTXt", data.data, data.size); } ucvector_cleanup(&compressed); ucvector_cleanup(&data); return error; } static unsigned addChunk_iTXt(ucvector* out, unsigned compressed, const char* keyword, const char* langtag, const char* transkey, const char* textstring, LodePNGCompressSettings* zlibsettings) { unsigned error = 0; ucvector data; size_t i, textsize = strlen(textstring); ucvector_init(&data); for(i = 0; keyword[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)keyword[i]); if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/ ucvector_push_back(&data, 0); /*null termination char*/ ucvector_push_back(&data, compressed ? 1 : 0); /*compression flag*/ ucvector_push_back(&data, 0); /*compression method*/ for(i = 0; langtag[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)langtag[i]); ucvector_push_back(&data, 0); /*null termination char*/ for(i = 0; transkey[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)transkey[i]); ucvector_push_back(&data, 0); /*null termination char*/ if(compressed) { ucvector compressed_data; ucvector_init(&compressed_data); error = zlib_compress(&compressed_data.data, &compressed_data.size, (unsigned char*)textstring, textsize, zlibsettings); if(!error) { for(i = 0; i != compressed_data.size; ++i) ucvector_push_back(&data, compressed_data.data[i]); } ucvector_cleanup(&compressed_data); } else /*not compressed*/ { for(i = 0; textstring[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)textstring[i]); } if(!error) error = addChunk(out, "iTXt", data.data, data.size); ucvector_cleanup(&data); return error; } static unsigned addChunk_bKGD(ucvector* out, const LodePNGInfo* info) { unsigned error = 0; ucvector bKGD; ucvector_init(&bKGD); if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA) { ucvector_push_back(&bKGD, (unsigned char)(info->background_r >> 8)); ucvector_push_back(&bKGD, (unsigned char)(info->background_r & 255)); } else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA) { ucvector_push_back(&bKGD, (unsigned char)(info->background_r >> 8)); ucvector_push_back(&bKGD, (unsigned char)(info->background_r & 255)); ucvector_push_back(&bKGD, (unsigned char)(info->background_g >> 8)); ucvector_push_back(&bKGD, (unsigned char)(info->background_g & 255)); ucvector_push_back(&bKGD, (unsigned char)(info->background_b >> 8)); ucvector_push_back(&bKGD, (unsigned char)(info->background_b & 255)); } else if(info->color.colortype == LCT_PALETTE) { ucvector_push_back(&bKGD, (unsigned char)(info->background_r & 255)); /*palette index*/ } error = addChunk(out, "bKGD", bKGD.data, bKGD.size); ucvector_cleanup(&bKGD); return error; } static unsigned addChunk_tIME(ucvector* out, const LodePNGTime* time) { unsigned error = 0; unsigned char* data = (unsigned char*)lodepng_malloc(7); if(!data) return 83; /*alloc fail*/ data[0] = (unsigned char)(time->year >> 8); data[1] = (unsigned char)(time->year & 255); data[2] = (unsigned char)time->month; data[3] = (unsigned char)time->day; data[4] = (unsigned char)time->hour; data[5] = (unsigned char)time->minute; data[6] = (unsigned char)time->second; error = addChunk(out, "tIME", data, 7); lodepng_free(data); return error; } static unsigned addChunk_pHYs(ucvector* out, const LodePNGInfo* info) { unsigned error = 0; ucvector data; ucvector_init(&data); lodepng_add32bitInt(&data, info->phys_x); lodepng_add32bitInt(&data, info->phys_y); ucvector_push_back(&data, info->phys_unit); error = addChunk(out, "pHYs", data.data, data.size); ucvector_cleanup(&data); return error; } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ static void filterScanline(unsigned char* out, const unsigned char* scanline, const unsigned char* prevline, size_t length, size_t bytewidth, unsigned char filterType) { size_t i; switch(filterType) { case 0: /*None*/ for(i = 0; i != length; ++i) out[i] = scanline[i]; break; case 1: /*Sub*/ for(i = 0; i != bytewidth; ++i) out[i] = scanline[i]; for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - scanline[i - bytewidth]; break; case 2: /*Up*/ if(prevline) { for(i = 0; i != length; ++i) out[i] = scanline[i] - prevline[i]; } else { for(i = 0; i != length; ++i) out[i] = scanline[i]; } break; case 3: /*Average*/ if(prevline) { for(i = 0; i != bytewidth; ++i) out[i] = scanline[i] - (prevline[i] >> 1); for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - ((scanline[i - bytewidth] + prevline[i]) >> 1); } else { for(i = 0; i != bytewidth; ++i) out[i] = scanline[i]; for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - (scanline[i - bytewidth] >> 1); } break; case 4: /*Paeth*/ if(prevline) { /*paethPredictor(0, prevline[i], 0) is always prevline[i]*/ for(i = 0; i != bytewidth; ++i) out[i] = (scanline[i] - prevline[i]); for(i = bytewidth; i < length; ++i) { out[i] = (scanline[i] - paethPredictor(scanline[i - bytewidth], prevline[i], prevline[i - bytewidth])); } } else { for(i = 0; i != bytewidth; ++i) out[i] = scanline[i]; /*paethPredictor(scanline[i - bytewidth], 0, 0) is always scanline[i - bytewidth]*/ for(i = bytewidth; i < length; ++i) out[i] = (scanline[i] - scanline[i - bytewidth]); } break; default: return; /*unexisting filter type given*/ } } /* log2 approximation. A slight bit faster than std::log. */ static float flog2(float f) { float result = 0; while(f > 32) { result += 4; f /= 16; } while(f > 2) { ++result; f /= 2; } return result + 1.442695f * (f * f * f / 3 - 3 * f * f / 2 + 3 * f - 1.83333f); } static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, const LodePNGColorMode* info, const LodePNGEncoderSettings* settings) { /* For PNG filter method 0 out must be a buffer with as size: h + (w * h * bpp + 7) / 8, because there are the scanlines with 1 extra byte per scanline */ unsigned bpp = lodepng_get_bpp(info); /*the width of a scanline in bytes, not including the filter type*/ size_t linebytes = (w * bpp + 7) / 8; /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/ size_t bytewidth = (bpp + 7) / 8; const unsigned char* prevline = 0; unsigned x, y; unsigned error = 0; LodePNGFilterStrategy strategy = settings->filter_strategy; /* There is a heuristic called the minimum sum of absolute differences heuristic, suggested by the PNG standard: * If the image type is Palette, or the bit depth is smaller than 8, then do not filter the image (i.e. use fixed filtering, with the filter None). * (The other case) If the image type is Grayscale or RGB (with or without Alpha), and the bit depth is not smaller than 8, then use adaptive filtering heuristic as follows: independently for each row, apply all five filters and select the filter that produces the smallest sum of absolute values per row. This heuristic is used if filter strategy is LFS_MINSUM and filter_palette_zero is true. If filter_palette_zero is true and filter_strategy is not LFS_MINSUM, the above heuristic is followed, but for "the other case", whatever strategy filter_strategy is set to instead of the minimum sum heuristic is used. */ if(settings->filter_palette_zero && (info->colortype == LCT_PALETTE || info->bitdepth < 8)) strategy = LFS_ZERO; if(bpp == 0) return 31; /*error: invalid color type*/ if(strategy == LFS_ZERO) { for(y = 0; y != h; ++y) { size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ size_t inindex = linebytes * y; out[outindex] = 0; /*filter type byte*/ filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, 0); prevline = &in[inindex]; } } else if(strategy == LFS_MINSUM) { /*adaptive filtering*/ size_t sum[5]; unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/ size_t smallest = 0; unsigned char type, bestType = 0; for(type = 0; type != 5; ++type) { attempt[type] = (unsigned char*)lodepng_malloc(linebytes); if(!attempt[type]) return 83; /*alloc fail*/ } if(!error) { for(y = 0; y != h; ++y) { /*try the 5 filter types*/ for(type = 0; type != 5; ++type) { filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type); /*calculate the sum of the result*/ sum[type] = 0; if(type == 0) { for(x = 0; x != linebytes; ++x) sum[type] += (unsigned char)(attempt[type][x]); } else { for(x = 0; x != linebytes; ++x) { /*For differences, each byte should be treated as signed, values above 127 are negative (converted to signed char). Filtertype 0 isn't a difference though, so use unsigned there. This means filtertype 0 is almost never chosen, but that is justified.*/ unsigned char s = attempt[type][x]; sum[type] += s < 128 ? s : (255U - s); } } /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/ if(type == 0 || sum[type] < smallest) { bestType = type; smallest = sum[type]; } } prevline = &in[y * linebytes]; /*now fill the out values*/ out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x]; } } for(type = 0; type != 5; ++type) lodepng_free(attempt[type]); } else if(strategy == LFS_ENTROPY) { float sum[5]; unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/ float smallest = 0; unsigned type, bestType = 0; unsigned count[256]; for(type = 0; type != 5; ++type) { attempt[type] = (unsigned char*)lodepng_malloc(linebytes); if(!attempt[type]) return 83; /*alloc fail*/ } for(y = 0; y != h; ++y) { /*try the 5 filter types*/ for(type = 0; type != 5; ++type) { filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type); for(x = 0; x != 256; ++x) count[x] = 0; for(x = 0; x != linebytes; ++x) ++count[attempt[type][x]]; ++count[type]; /*the filter type itself is part of the scanline*/ sum[type] = 0; for(x = 0; x != 256; ++x) { float p = count[x] / (float)(linebytes + 1); sum[type] += count[x] == 0 ? 0 : flog2(1 / p) * p; } /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/ if(type == 0 || sum[type] < smallest) { bestType = type; smallest = sum[type]; } } prevline = &in[y * linebytes]; /*now fill the out values*/ out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x]; } for(type = 0; type != 5; ++type) lodepng_free(attempt[type]); } else if(strategy == LFS_PREDEFINED) { for(y = 0; y != h; ++y) { size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ size_t inindex = linebytes * y; unsigned char type = settings->predefined_filters[y]; out[outindex] = type; /*filter type byte*/ filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, type); prevline = &in[inindex]; } } else if(strategy == LFS_BRUTE_FORCE) { /*brute force filter chooser. deflate the scanline after every filter attempt to see which one deflates best. This is very slow and gives only slightly smaller, sometimes even larger, result*/ size_t size[5]; unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/ size_t smallest = 0; unsigned type = 0, bestType = 0; unsigned char* dummy; LodePNGCompressSettings zlibsettings = settings->zlibsettings; /*use fixed tree on the attempts so that the tree is not adapted to the filtertype on purpose, to simulate the true case where the tree is the same for the whole image. Sometimes it gives better result with dynamic tree anyway. Using the fixed tree sometimes gives worse, but in rare cases better compression. It does make this a bit less slow, so it's worth doing this.*/ zlibsettings.btype = 1; /*a custom encoder likely doesn't read the btype setting and is optimized for complete PNG images only, so disable it*/ zlibsettings.custom_zlib = 0; zlibsettings.custom_deflate = 0; for(type = 0; type != 5; ++type) { attempt[type] = (unsigned char*)lodepng_malloc(linebytes); if(!attempt[type]) return 83; /*alloc fail*/ } for(y = 0; y != h; ++y) /*try the 5 filter types*/ { for(type = 0; type != 5; ++type) { unsigned testsize = linebytes; /*if(testsize > 8) testsize /= 8;*/ /*it already works good enough by testing a part of the row*/ filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type); size[type] = 0; dummy = 0; zlib_compress(&dummy, &size[type], attempt[type], testsize, &zlibsettings); lodepng_free(dummy); /*check if this is smallest size (or if type == 0 it's the first case so always store the values)*/ if(type == 0 || size[type] < smallest) { bestType = type; smallest = size[type]; } } prevline = &in[y * linebytes]; out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x]; } for(type = 0; type != 5; ++type) lodepng_free(attempt[type]); } else return 88; /* unknown filter strategy */ return error; } static void addPaddingBits(unsigned char* out, const unsigned char* in, size_t olinebits, size_t ilinebits, unsigned h) { /*The opposite of the removePaddingBits function olinebits must be >= ilinebits*/ unsigned y; size_t diff = olinebits - ilinebits; size_t obp = 0, ibp = 0; /*bit pointers*/ for(y = 0; y != h; ++y) { size_t x; for(x = 0; x < ilinebits; ++x) { unsigned char bit = readBitFromReversedStream(&ibp, in); setBitOfReversedStream(&obp, out, bit); } /*obp += diff; --> no, fill in some value in the padding bits too, to avoid "Use of uninitialised value of size ###" warning from valgrind*/ for(x = 0; x != diff; ++x) setBitOfReversedStream(&obp, out, 0); } } /* in: non-interlaced image with size w*h out: the same pixels, but re-ordered according to PNG's Adam7 interlacing, with no padding bits between scanlines, but between reduced images so that each reduced image starts at a byte. bpp: bits per pixel there are no padding bits, not between scanlines, not between reduced images in has the following size in bits: w * h * bpp. out is possibly bigger due to padding bits between reduced images NOTE: comments about padding bits are only relevant if bpp < 8 */ static void Adam7_interlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) { unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8]; unsigned i; Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); if(bpp >= 8) { for(i = 0; i != 7; ++i) { unsigned x, y, b; size_t bytewidth = bpp / 8; for(y = 0; y < passh[i]; ++y) for(x = 0; x < passw[i]; ++x) { size_t pixelinstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth; size_t pixeloutstart = passstart[i] + (y * passw[i] + x) * bytewidth; for(b = 0; b < bytewidth; ++b) { out[pixeloutstart + b] = in[pixelinstart + b]; } } } } else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/ { for(i = 0; i != 7; ++i) { unsigned x, y, b; unsigned ilinebits = bpp * passw[i]; unsigned olinebits = bpp * w; size_t obp, ibp; /*bit pointers (for out and in buffer)*/ for(y = 0; y < passh[i]; ++y) for(x = 0; x < passw[i]; ++x) { ibp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp; obp = (8 * passstart[i]) + (y * ilinebits + x * bpp); for(b = 0; b < bpp; ++b) { unsigned char bit = readBitFromReversedStream(&ibp, in); setBitOfReversedStream(&obp, out, bit); } } } } } /*out must be buffer big enough to contain uncompressed IDAT chunk data, and in must contain the full image. return value is error**/ static unsigned preProcessScanlines(unsigned char** out, size_t* outsize, const unsigned char* in, unsigned w, unsigned h, const LodePNGInfo* info_png, const LodePNGEncoderSettings* settings) { /* This function converts the pure 2D image with the PNG's colortype, into filtered-padded-interlaced data. Steps: *) if no Adam7: 1) add padding bits (= posible extra bits per scanline if bpp < 8) 2) filter *) if adam7: 1) Adam7_interlace 2) 7x add padding bits 3) 7x filter */ unsigned bpp = lodepng_get_bpp(&info_png->color); unsigned error = 0; if(info_png->interlace_method == 0) { *outsize = h + (h * ((w * bpp + 7) / 8)); /*image size plus an extra byte per scanline + possible padding bits*/ *out = (unsigned char*)lodepng_malloc(*outsize); if(!(*out) && (*outsize)) error = 83; /*alloc fail*/ if(!error) { /*non multiple of 8 bits per scanline, padding bits needed per scanline*/ if(bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8) { unsigned char* padded = (unsigned char*)lodepng_malloc(h * ((w * bpp + 7) / 8)); if(!padded) error = 83; /*alloc fail*/ if(!error) { addPaddingBits(padded, in, ((w * bpp + 7) / 8) * 8, w * bpp, h); error = filter(*out, padded, w, h, &info_png->color, settings); } lodepng_free(padded); } else { /*we can immediately filter into the out buffer, no other steps needed*/ error = filter(*out, in, w, h, &info_png->color, settings); } } } else /*interlace_method is 1 (Adam7)*/ { unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8]; unsigned char* adam7; Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); *outsize = filter_passstart[7]; /*image size plus an extra byte per scanline + possible padding bits*/ *out = (unsigned char*)lodepng_malloc(*outsize); if(!(*out)) error = 83; /*alloc fail*/ adam7 = (unsigned char*)lodepng_malloc(passstart[7]); if(!adam7 && passstart[7]) error = 83; /*alloc fail*/ if(!error) { unsigned i; Adam7_interlace(adam7, in, w, h, bpp); for(i = 0; i != 7; ++i) { if(bpp < 8) { unsigned char* padded = (unsigned char*)lodepng_malloc(padded_passstart[i + 1] - padded_passstart[i]); if(!padded) ERROR_BREAK(83); /*alloc fail*/ addPaddingBits(padded, &adam7[passstart[i]], ((passw[i] * bpp + 7) / 8) * 8, passw[i] * bpp, passh[i]); error = filter(&(*out)[filter_passstart[i]], padded, passw[i], passh[i], &info_png->color, settings); lodepng_free(padded); } else { error = filter(&(*out)[filter_passstart[i]], &adam7[padded_passstart[i]], passw[i], passh[i], &info_png->color, settings); } if(error) break; } } lodepng_free(adam7); } return error; } /* palette must have 4 * palettesize bytes allocated, and given in format RGBARGBARGBARGBA... returns 0 if the palette is opaque, returns 1 if the palette has a single color with alpha 0 ==> color key returns 2 if the palette is semi-translucent. */ static unsigned getPaletteTranslucency(const unsigned char* palette, size_t palettesize) { size_t i; unsigned key = 0; unsigned r = 0, g = 0, b = 0; /*the value of the color with alpha 0, so long as color keying is possible*/ for(i = 0; i != palettesize; ++i) { if(!key && palette[4 * i + 3] == 0) { r = palette[4 * i + 0]; g = palette[4 * i + 1]; b = palette[4 * i + 2]; key = 1; i = (size_t)(-1); /*restart from beginning, to detect earlier opaque colors with key's value*/ } else if(palette[4 * i + 3] != 255) return 2; /*when key, no opaque RGB may have key's RGB*/ else if(key && r == palette[i * 4 + 0] && g == palette[i * 4 + 1] && b == palette[i * 4 + 2]) return 2; } return key; } #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS static unsigned addUnknownChunks(ucvector* out, unsigned char* data, size_t datasize) { unsigned char* inchunk = data; while((size_t)(inchunk - data) < datasize) { CERROR_TRY_RETURN(lodepng_chunk_append(&out->data, &out->size, inchunk)); out->allocsize = out->size; /*fix the allocsize again*/ inchunk = lodepng_chunk_next(inchunk); } return 0; } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ unsigned lodepng_encode(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h, LodePNGState* state) { LodePNGInfo info; ucvector outv; unsigned char* data = 0; /*uncompressed version of the IDAT chunk data*/ size_t datasize = 0; /*provide some proper output values if error will happen*/ *out = 0; *outsize = 0; state->error = 0; lodepng_info_init(&info); lodepng_info_copy(&info, &state->info_png); if((info.color.colortype == LCT_PALETTE || state->encoder.force_palette) && (info.color.palettesize == 0 || info.color.palettesize > 256)) { state->error = 68; /*invalid palette size, it is only allowed to be 1-256*/ return state->error; } if(state->encoder.auto_convert) { state->error = lodepng_auto_choose_color(&info.color, image, w, h, &state->info_raw); } if(state->error) return state->error; if(state->encoder.zlibsettings.btype > 2) { CERROR_RETURN_ERROR(state->error, 61); /*error: unexisting btype*/ } if(state->info_png.interlace_method > 1) { CERROR_RETURN_ERROR(state->error, 71); /*error: unexisting interlace mode*/ } state->error = checkColorValidity(info.color.colortype, info.color.bitdepth); if(state->error) return state->error; /*error: unexisting color type given*/ state->error = checkColorValidity(state->info_raw.colortype, state->info_raw.bitdepth); if(state->error) return state->error; /*error: unexisting color type given*/ if(!lodepng_color_mode_equal(&state->info_raw, &info.color)) { unsigned char* converted; size_t size = (w * h * (size_t)lodepng_get_bpp(&info.color) + 7) / 8; converted = (unsigned char*)lodepng_malloc(size); if(!converted && size) state->error = 83; /*alloc fail*/ if(!state->error) { state->error = lodepng_convert(converted, image, &info.color, &state->info_raw, w, h); } if(!state->error) preProcessScanlines(&data, &datasize, converted, w, h, &info, &state->encoder); lodepng_free(converted); } else preProcessScanlines(&data, &datasize, image, w, h, &info, &state->encoder); ucvector_init(&outv); while(!state->error) /*while only executed once, to break on error*/ { #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS size_t i; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ /*write signature and chunks*/ writeSignature(&outv); /*IHDR*/ addChunk_IHDR(&outv, w, h, info.color.colortype, info.color.bitdepth, info.interlace_method); #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /*unknown chunks between IHDR and PLTE*/ if(info.unknown_chunks_data[0]) { state->error = addUnknownChunks(&outv, info.unknown_chunks_data[0], info.unknown_chunks_size[0]); if(state->error) break; } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ /*PLTE*/ if(info.color.colortype == LCT_PALETTE) { addChunk_PLTE(&outv, &info.color); } if(state->encoder.force_palette && (info.color.colortype == LCT_RGB || info.color.colortype == LCT_RGBA)) { addChunk_PLTE(&outv, &info.color); } /*tRNS*/ if(info.color.colortype == LCT_PALETTE && getPaletteTranslucency(info.color.palette, info.color.palettesize) != 0) { addChunk_tRNS(&outv, &info.color); } if((info.color.colortype == LCT_GREY || info.color.colortype == LCT_RGB) && info.color.key_defined) { addChunk_tRNS(&outv, &info.color); } #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /*bKGD (must come between PLTE and the IDAt chunks*/ if(info.background_defined) addChunk_bKGD(&outv, &info); /*pHYs (must come before the IDAT chunks)*/ if(info.phys_defined) addChunk_pHYs(&outv, &info); /*unknown chunks between PLTE and IDAT*/ if(info.unknown_chunks_data[1]) { state->error = addUnknownChunks(&outv, info.unknown_chunks_data[1], info.unknown_chunks_size[1]); if(state->error) break; } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ /*IDAT (multiple IDAT chunks must be consecutive)*/ state->error = addChunk_IDAT(&outv, data, datasize, &state->encoder.zlibsettings); if(state->error) break; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /*tIME*/ if(info.time_defined) addChunk_tIME(&outv, &info.time); /*tEXt and/or zTXt*/ for(i = 0; i != info.text_num; ++i) { if(strlen(info.text_keys[i]) > 79) { state->error = 66; /*text chunk too large*/ break; } if(strlen(info.text_keys[i]) < 1) { state->error = 67; /*text chunk too small*/ break; } if(state->encoder.text_compression) { addChunk_zTXt(&outv, info.text_keys[i], info.text_strings[i], &state->encoder.zlibsettings); } else { addChunk_tEXt(&outv, info.text_keys[i], info.text_strings[i]); } } /*LodePNG version id in text chunk*/ if(state->encoder.add_id) { unsigned alread_added_id_text = 0; for(i = 0; i != info.text_num; ++i) { if(!strcmp(info.text_keys[i], "LodePNG")) { alread_added_id_text = 1; break; } } if(alread_added_id_text == 0) { addChunk_tEXt(&outv, "LodePNG", LODEPNG_VERSION_STRING); /*it's shorter as tEXt than as zTXt chunk*/ } } /*iTXt*/ for(i = 0; i != info.itext_num; ++i) { if(strlen(info.itext_keys[i]) > 79) { state->error = 66; /*text chunk too large*/ break; } if(strlen(info.itext_keys[i]) < 1) { state->error = 67; /*text chunk too small*/ break; } addChunk_iTXt(&outv, state->encoder.text_compression, info.itext_keys[i], info.itext_langtags[i], info.itext_transkeys[i], info.itext_strings[i], &state->encoder.zlibsettings); } /*unknown chunks between IDAT and IEND*/ if(info.unknown_chunks_data[2]) { state->error = addUnknownChunks(&outv, info.unknown_chunks_data[2], info.unknown_chunks_size[2]); if(state->error) break; } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ addChunk_IEND(&outv); break; /*this isn't really a while loop; no error happened so break out now!*/ } lodepng_info_cleanup(&info); lodepng_free(data); /*instead of cleaning the vector up, give it to the output*/ *out = outv.data; *outsize = outv.size; return state->error; } unsigned lodepng_encode_memory(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) { unsigned error; LodePNGState state; lodepng_state_init(&state); state.info_raw.colortype = colortype; state.info_raw.bitdepth = bitdepth; state.info_png.color.colortype = colortype; state.info_png.color.bitdepth = bitdepth; lodepng_encode(out, outsize, image, w, h, &state); error = state.error; lodepng_state_cleanup(&state); return error; } unsigned lodepng_encode32(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h) { return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGBA, 8); } unsigned lodepng_encode24(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h) { return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGB, 8); } #ifdef LODEPNG_COMPILE_DISK unsigned lodepng_encode_file(const char* filename, const unsigned char* image, unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) { unsigned char* buffer; size_t buffersize; unsigned error = lodepng_encode_memory(&buffer, &buffersize, image, w, h, colortype, bitdepth); if(!error) error = lodepng_save_file(buffer, buffersize, filename); lodepng_free(buffer); return error; } unsigned lodepng_encode32_file(const char* filename, const unsigned char* image, unsigned w, unsigned h) { return lodepng_encode_file(filename, image, w, h, LCT_RGBA, 8); } unsigned lodepng_encode24_file(const char* filename, const unsigned char* image, unsigned w, unsigned h) { return lodepng_encode_file(filename, image, w, h, LCT_RGB, 8); } #endif /*LODEPNG_COMPILE_DISK*/ void lodepng_encoder_settings_init(LodePNGEncoderSettings* settings) { lodepng_compress_settings_init(&settings->zlibsettings); settings->filter_palette_zero = 1; settings->filter_strategy = LFS_MINSUM; settings->auto_convert = 1; settings->force_palette = 0; settings->predefined_filters = 0; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS settings->add_id = 0; settings->text_compression = 1; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } #endif /*LODEPNG_COMPILE_ENCODER*/ #endif /*LODEPNG_COMPILE_PNG*/ #ifdef LODEPNG_COMPILE_ERROR_TEXT /* This returns the description of a numerical error code in English. This is also the documentation of all the error codes. */ const char* lodepng_error_text(unsigned code) { switch(code) { case 0: return "no error, everything went ok"; case 1: return "nothing done yet"; /*the Encoder/Decoder has done nothing yet, error checking makes no sense yet*/ case 10: return "end of input memory reached without huffman end code"; /*while huffman decoding*/ case 11: return "error in code tree made it jump outside of huffman tree"; /*while huffman decoding*/ case 13: return "problem while processing dynamic deflate block"; case 14: return "problem while processing dynamic deflate block"; case 15: return "problem while processing dynamic deflate block"; case 16: return "unexisting code while processing dynamic deflate block"; case 17: return "end of out buffer memory reached while inflating"; case 18: return "invalid distance code while inflating"; case 19: return "end of out buffer memory reached while inflating"; case 20: return "invalid deflate block BTYPE encountered while decoding"; case 21: return "NLEN is not ones complement of LEN in a deflate block"; /*end of out buffer memory reached while inflating: This can happen if the inflated deflate data is longer than the amount of bytes required to fill up all the pixels of the image, given the color depth and image dimensions. Something that doesn't happen in a normal, well encoded, PNG image.*/ case 22: return "end of out buffer memory reached while inflating"; case 23: return "end of in buffer memory reached while inflating"; case 24: return "invalid FCHECK in zlib header"; case 25: return "invalid compression method in zlib header"; case 26: return "FDICT encountered in zlib header while it's not used for PNG"; case 27: return "PNG file is smaller than a PNG header"; /*Checks the magic file header, the first 8 bytes of the PNG file*/ case 28: return "incorrect PNG signature, it's no PNG or corrupted"; case 29: return "first chunk is not the header chunk"; case 30: return "chunk length too large, chunk broken off at end of file"; case 31: return "illegal PNG color type or bpp"; case 32: return "illegal PNG compression method"; case 33: return "illegal PNG filter method"; case 34: return "illegal PNG interlace method"; case 35: return "chunk length of a chunk is too large or the chunk too small"; case 36: return "illegal PNG filter type encountered"; case 37: return "illegal bit depth for this color type given"; case 38: return "the palette is too big"; /*more than 256 colors*/ case 39: return "more palette alpha values given in tRNS chunk than there are colors in the palette"; case 40: return "tRNS chunk has wrong size for greyscale image"; case 41: return "tRNS chunk has wrong size for RGB image"; case 42: return "tRNS chunk appeared while it was not allowed for this color type"; case 43: return "bKGD chunk has wrong size for palette image"; case 44: return "bKGD chunk has wrong size for greyscale image"; case 45: return "bKGD chunk has wrong size for RGB image"; case 48: return "empty input buffer given to decoder. Maybe caused by non-existing file?"; case 49: return "jumped past memory while generating dynamic huffman tree"; case 50: return "jumped past memory while generating dynamic huffman tree"; case 51: return "jumped past memory while inflating huffman block"; case 52: return "jumped past memory while inflating"; case 53: return "size of zlib data too small"; case 54: return "repeat symbol in tree while there was no value symbol yet"; /*jumped past tree while generating huffman tree, this could be when the tree will have more leaves than symbols after generating it out of the given lenghts. They call this an oversubscribed dynamic bit lengths tree in zlib.*/ case 55: return "jumped past tree while generating huffman tree"; case 56: return "given output image colortype or bitdepth not supported for color conversion"; case 57: return "invalid CRC encountered (checking CRC can be disabled)"; case 58: return "invalid ADLER32 encountered (checking ADLER32 can be disabled)"; case 59: return "requested color conversion not supported"; case 60: return "invalid window size given in the settings of the encoder (must be 0-32768)"; case 61: return "invalid BTYPE given in the settings of the encoder (only 0, 1 and 2 are allowed)"; /*LodePNG leaves the choice of RGB to greyscale conversion formula to the user.*/ case 62: return "conversion from color to greyscale not supported"; case 63: return "length of a chunk too long, max allowed for PNG is 2147483647 bytes per chunk"; /*(2^31-1)*/ /*this would result in the inability of a deflated block to ever contain an end code. It must be at least 1.*/ case 64: return "the length of the END symbol 256 in the Huffman tree is 0"; case 66: return "the length of a text chunk keyword given to the encoder is longer than the maximum of 79 bytes"; case 67: return "the length of a text chunk keyword given to the encoder is smaller than the minimum of 1 byte"; case 68: return "tried to encode a PLTE chunk with a palette that has less than 1 or more than 256 colors"; case 69: return "unknown chunk type with 'critical' flag encountered by the decoder"; case 71: return "unexisting interlace mode given to encoder (must be 0 or 1)"; case 72: return "while decoding, unexisting compression method encountering in zTXt or iTXt chunk (it must be 0)"; case 73: return "invalid tIME chunk size"; case 74: return "invalid pHYs chunk size"; /*length could be wrong, or data chopped off*/ case 75: return "no null termination char found while decoding text chunk"; case 76: return "iTXt chunk too short to contain required bytes"; case 77: return "integer overflow in buffer size"; case 78: return "failed to open file for reading"; /*file doesn't exist or couldn't be opened for reading*/ case 79: return "failed to open file for writing"; case 80: return "tried creating a tree of 0 symbols"; case 81: return "lazy matching at pos 0 is impossible"; case 82: return "color conversion to palette requested while a color isn't in palette"; case 83: return "memory allocation failed"; case 84: return "given image too small to contain all pixels to be encoded"; case 86: return "impossible offset in lz77 encoding (internal bug)"; case 87: return "must provide custom zlib function pointer if LODEPNG_COMPILE_ZLIB is not defined"; case 88: return "invalid filter strategy given for LodePNGEncoderSettings.filter_strategy"; case 89: return "text chunk keyword too short or long: must have size 1-79"; /*the windowsize in the LodePNGCompressSettings. Requiring POT(==> & instead of %) makes encoding 12% faster.*/ case 90: return "windowsize must be a power of two"; case 91: return "invalid decompressed idat size"; case 92: return "too many pixels, not supported"; case 93: return "zero width or height is invalid"; case 94: return "header chunk must have a size of 13 bytes"; } return "unknown error code"; } #endif /*LODEPNG_COMPILE_ERROR_TEXT*/ /* ////////////////////////////////////////////////////////////////////////// */ /* ////////////////////////////////////////////////////////////////////////// */ /* // C++ Wrapper // */ /* ////////////////////////////////////////////////////////////////////////// */ /* ////////////////////////////////////////////////////////////////////////// */ #ifdef LODEPNG_COMPILE_CPP namespace lodepng { #ifdef LODEPNG_COMPILE_DISK unsigned load_file(std::vector& buffer, const std::string& filename) { long size = lodepng_filesize(filename.c_str()); if(size < 0) return 78; buffer.resize((size_t)size); return size == 0 ? 0 : lodepng_buffer_file(&buffer[0], (size_t)size, filename.c_str()); } /*write given buffer to the file, overwriting the file, it doesn't append to it.*/ unsigned save_file(const std::vector& buffer, const std::string& filename) { return lodepng_save_file(buffer.empty() ? 0 : &buffer[0], buffer.size(), filename.c_str()); } #endif /* LODEPNG_COMPILE_DISK */ #ifdef LODEPNG_COMPILE_ZLIB #ifdef LODEPNG_COMPILE_DECODER unsigned decompress(std::vector& out, const unsigned char* in, size_t insize, const LodePNGDecompressSettings& settings) { unsigned char* buffer = 0; size_t buffersize = 0; unsigned error = zlib_decompress(&buffer, &buffersize, in, insize, &settings); if(buffer) { out.insert(out.end(), &buffer[0], &buffer[buffersize]); lodepng_free(buffer); } return error; } unsigned decompress(std::vector& out, const std::vector& in, const LodePNGDecompressSettings& settings) { return decompress(out, in.empty() ? 0 : &in[0], in.size(), settings); } #endif /* LODEPNG_COMPILE_DECODER */ #ifdef LODEPNG_COMPILE_ENCODER unsigned compress(std::vector& out, const unsigned char* in, size_t insize, const LodePNGCompressSettings& settings) { unsigned char* buffer = 0; size_t buffersize = 0; unsigned error = zlib_compress(&buffer, &buffersize, in, insize, &settings); if(buffer) { out.insert(out.end(), &buffer[0], &buffer[buffersize]); lodepng_free(buffer); } return error; } unsigned compress(std::vector& out, const std::vector& in, const LodePNGCompressSettings& settings) { return compress(out, in.empty() ? 0 : &in[0], in.size(), settings); } #endif /* LODEPNG_COMPILE_ENCODER */ #endif /* LODEPNG_COMPILE_ZLIB */ #ifdef LODEPNG_COMPILE_PNG State::State() { lodepng_state_init(this); } State::State(const State& other) { lodepng_state_init(this); lodepng_state_copy(this, &other); } State::~State() { lodepng_state_cleanup(this); } State& State::operator=(const State& other) { lodepng_state_copy(this, &other); return *this; } #ifdef LODEPNG_COMPILE_DECODER unsigned decode(std::vector& out, unsigned& w, unsigned& h, const unsigned char* in, size_t insize, LodePNGColorType colortype, unsigned bitdepth) { unsigned char* buffer; unsigned error = lodepng_decode_memory(&buffer, &w, &h, in, insize, colortype, bitdepth); if(buffer && !error) { State state; state.info_raw.colortype = colortype; state.info_raw.bitdepth = bitdepth; size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw); out.insert(out.end(), &buffer[0], &buffer[buffersize]); lodepng_free(buffer); } return error; } unsigned decode(std::vector& out, unsigned& w, unsigned& h, const std::vector& in, LodePNGColorType colortype, unsigned bitdepth) { return decode(out, w, h, in.empty() ? 0 : &in[0], (unsigned)in.size(), colortype, bitdepth); } unsigned decode(std::vector& out, unsigned& w, unsigned& h, State& state, const unsigned char* in, size_t insize) { unsigned char* buffer = NULL; unsigned error = lodepng_decode(&buffer, &w, &h, &state, in, insize); if(buffer && !error) { size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw); out.insert(out.end(), &buffer[0], &buffer[buffersize]); } lodepng_free(buffer); return error; } unsigned decode(std::vector& out, unsigned& w, unsigned& h, State& state, const std::vector& in) { return decode(out, w, h, state, in.empty() ? 0 : &in[0], in.size()); } #ifdef LODEPNG_COMPILE_DISK unsigned decode(std::vector& out, unsigned& w, unsigned& h, const std::string& filename, LodePNGColorType colortype, unsigned bitdepth) { std::vector buffer; unsigned error = load_file(buffer, filename); if(error) return error; return decode(out, w, h, buffer, colortype, bitdepth); } #endif /* LODEPNG_COMPILE_DECODER */ #endif /* LODEPNG_COMPILE_DISK */ #ifdef LODEPNG_COMPILE_ENCODER unsigned encode(std::vector& out, const unsigned char* in, unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) { unsigned char* buffer; size_t buffersize; unsigned error = lodepng_encode_memory(&buffer, &buffersize, in, w, h, colortype, bitdepth); if(buffer) { out.insert(out.end(), &buffer[0], &buffer[buffersize]); lodepng_free(buffer); } return error; } unsigned encode(std::vector& out, const std::vector& in, unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) { if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84; return encode(out, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth); } unsigned encode(std::vector& out, const unsigned char* in, unsigned w, unsigned h, State& state) { unsigned char* buffer; size_t buffersize; unsigned error = lodepng_encode(&buffer, &buffersize, in, w, h, &state); if(buffer) { out.insert(out.end(), &buffer[0], &buffer[buffersize]); lodepng_free(buffer); } return error; } unsigned encode(std::vector& out, const std::vector& in, unsigned w, unsigned h, State& state) { if(lodepng_get_raw_size(w, h, &state.info_raw) > in.size()) return 84; return encode(out, in.empty() ? 0 : &in[0], w, h, state); } #ifdef LODEPNG_COMPILE_DISK unsigned encode(const std::string& filename, const unsigned char* in, unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) { std::vector buffer; unsigned error = encode(buffer, in, w, h, colortype, bitdepth); if(!error) error = save_file(buffer, filename); return error; } unsigned encode(const std::string& filename, const std::vector& in, unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) { if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84; return encode(filename, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth); } #endif /* LODEPNG_COMPILE_DISK */ #endif /* LODEPNG_COMPILE_ENCODER */ #endif /* LODEPNG_COMPILE_PNG */ } /* namespace lodepng */ #endif /*LODEPNG_COMPILE_CPP*/ libtcod-1.6.4+dfsg/src/png/lodepng.h000066400000000000000000002403541321276576200172600ustar00rootroot00000000000000/* LodePNG version 20160501 Copyright (c) 2005-2016 Lode Vandevenne This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ #ifndef LODEPNG_H #define LODEPNG_H #include /*for size_t*/ extern const char* LODEPNG_VERSION_STRING; /* The following #defines are used to create code sections. They can be disabled to disable code sections, which can give faster compile time and smaller binary. The "NO_COMPILE" defines are designed to be used to pass as defines to the compiler command to disable them without modifying this header, e.g. -DLODEPNG_NO_COMPILE_ZLIB for gcc. In addition to those below, you can also define LODEPNG_NO_COMPILE_CRC to allow implementing a custom lodepng_crc32. */ /*deflate & zlib. If disabled, you must specify alternative zlib functions in the custom_zlib field of the compress and decompress settings*/ #ifndef LODEPNG_NO_COMPILE_ZLIB #define LODEPNG_COMPILE_ZLIB #endif /*png encoder and png decoder*/ #ifndef LODEPNG_NO_COMPILE_PNG #define LODEPNG_COMPILE_PNG #endif /*deflate&zlib decoder and png decoder*/ #ifndef LODEPNG_NO_COMPILE_DECODER #define LODEPNG_COMPILE_DECODER #endif /*deflate&zlib encoder and png encoder*/ #ifndef LODEPNG_NO_COMPILE_ENCODER #define LODEPNG_COMPILE_ENCODER #endif /*the optional built in harddisk file loading and saving functions*/ #ifndef LODEPNG_NO_COMPILE_DISK #define LODEPNG_COMPILE_DISK #endif /*support for chunks other than IHDR, IDAT, PLTE, tRNS, IEND: ancillary and unknown chunks*/ #ifndef LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS #define LODEPNG_COMPILE_ANCILLARY_CHUNKS #endif /*ability to convert error numerical codes to English text string*/ #ifndef LODEPNG_NO_COMPILE_ERROR_TEXT #define LODEPNG_COMPILE_ERROR_TEXT #endif /*Compile the default allocators (C's free, malloc and realloc). If you disable this, you can define the functions lodepng_free, lodepng_malloc and lodepng_realloc in your source files with custom allocators.*/ #ifndef LODEPNG_NO_COMPILE_ALLOCATORS #define LODEPNG_COMPILE_ALLOCATORS #endif /*compile the C++ version (you can disable the C++ wrapper here even when compiling for C++)*/ #ifdef __cplusplus #ifndef LODEPNG_NO_COMPILE_CPP #define LODEPNG_COMPILE_CPP #endif #endif #ifdef LODEPNG_COMPILE_CPP #include #include #endif /*LODEPNG_COMPILE_CPP*/ #ifdef LODEPNG_COMPILE_PNG /*The PNG color types (also used for raw).*/ typedef enum LodePNGColorType { LCT_GREY = 0, /*greyscale: 1,2,4,8,16 bit*/ LCT_RGB = 2, /*RGB: 8,16 bit*/ LCT_PALETTE = 3, /*palette: 1,2,4,8 bit*/ LCT_GREY_ALPHA = 4, /*greyscale with alpha: 8,16 bit*/ LCT_RGBA = 6 /*RGB with alpha: 8,16 bit*/ } LodePNGColorType; #ifdef LODEPNG_COMPILE_DECODER /* Converts PNG data in memory to raw pixel data. out: Output parameter. Pointer to buffer that will contain the raw pixel data. After decoding, its size is w * h * (bytes per pixel) bytes larger than initially. Bytes per pixel depends on colortype and bitdepth. Must be freed after usage with free(*out). Note: for 16-bit per channel colors, uses big endian format like PNG does. w: Output parameter. Pointer to width of pixel data. h: Output parameter. Pointer to height of pixel data. in: Memory buffer with the PNG file. insize: size of the in buffer. colortype: the desired color type for the raw output image. See explanation on PNG color types. bitdepth: the desired bit depth for the raw output image. See explanation on PNG color types. Return value: LodePNG error code (0 means no error). */ unsigned lodepng_decode_memory(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize, LodePNGColorType colortype, unsigned bitdepth); /*Same as lodepng_decode_memory, but always decodes to 32-bit RGBA raw image*/ unsigned lodepng_decode32(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize); /*Same as lodepng_decode_memory, but always decodes to 24-bit RGB raw image*/ unsigned lodepng_decode24(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize); #ifdef LODEPNG_COMPILE_DISK /* Load PNG from disk, from file with given name. Same as the other decode functions, but instead takes a filename as input. */ unsigned lodepng_decode_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename, LodePNGColorType colortype, unsigned bitdepth); /*Same as lodepng_decode_file, but always decodes to 32-bit RGBA raw image.*/ unsigned lodepng_decode32_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename); /*Same as lodepng_decode_file, but always decodes to 24-bit RGB raw image.*/ unsigned lodepng_decode24_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename); #endif /*LODEPNG_COMPILE_DISK*/ #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER /* Converts raw pixel data into a PNG image in memory. The colortype and bitdepth of the output PNG image cannot be chosen, they are automatically determined by the colortype, bitdepth and content of the input pixel data. Note: for 16-bit per channel colors, needs big endian format like PNG does. out: Output parameter. Pointer to buffer that will contain the PNG image data. Must be freed after usage with free(*out). outsize: Output parameter. Pointer to the size in bytes of the out buffer. image: The raw pixel data to encode. The size of this buffer should be w * h * (bytes per pixel), bytes per pixel depends on colortype and bitdepth. w: width of the raw pixel data in pixels. h: height of the raw pixel data in pixels. colortype: the color type of the raw input image. See explanation on PNG color types. bitdepth: the bit depth of the raw input image. See explanation on PNG color types. Return value: LodePNG error code (0 means no error). */ unsigned lodepng_encode_memory(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth); /*Same as lodepng_encode_memory, but always encodes from 32-bit RGBA raw image.*/ unsigned lodepng_encode32(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h); /*Same as lodepng_encode_memory, but always encodes from 24-bit RGB raw image.*/ unsigned lodepng_encode24(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h); #ifdef LODEPNG_COMPILE_DISK /* Converts raw pixel data into a PNG file on disk. Same as the other encode functions, but instead takes a filename as output. NOTE: This overwrites existing files without warning! */ unsigned lodepng_encode_file(const char* filename, const unsigned char* image, unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth); /*Same as lodepng_encode_file, but always encodes from 32-bit RGBA raw image.*/ unsigned lodepng_encode32_file(const char* filename, const unsigned char* image, unsigned w, unsigned h); /*Same as lodepng_encode_file, but always encodes from 24-bit RGB raw image.*/ unsigned lodepng_encode24_file(const char* filename, const unsigned char* image, unsigned w, unsigned h); #endif /*LODEPNG_COMPILE_DISK*/ #endif /*LODEPNG_COMPILE_ENCODER*/ #ifdef LODEPNG_COMPILE_CPP namespace lodepng { #ifdef LODEPNG_COMPILE_DECODER /*Same as lodepng_decode_memory, but decodes to an std::vector. The colortype is the format to output the pixels to. Default is RGBA 8-bit per channel.*/ unsigned decode(std::vector& out, unsigned& w, unsigned& h, const unsigned char* in, size_t insize, LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); unsigned decode(std::vector& out, unsigned& w, unsigned& h, const std::vector& in, LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); #ifdef LODEPNG_COMPILE_DISK /* Converts PNG file from disk to raw pixel data in memory. Same as the other decode functions, but instead takes a filename as input. */ unsigned decode(std::vector& out, unsigned& w, unsigned& h, const std::string& filename, LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); #endif /* LODEPNG_COMPILE_DISK */ #endif /* LODEPNG_COMPILE_DECODER */ #ifdef LODEPNG_COMPILE_ENCODER /*Same as lodepng_encode_memory, but encodes to an std::vector. colortype is that of the raw input data. The output PNG color type will be auto chosen.*/ unsigned encode(std::vector& out, const unsigned char* in, unsigned w, unsigned h, LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); unsigned encode(std::vector& out, const std::vector& in, unsigned w, unsigned h, LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); #ifdef LODEPNG_COMPILE_DISK /* Converts 32-bit RGBA raw pixel data into a PNG file on disk. Same as the other encode functions, but instead takes a filename as output. NOTE: This overwrites existing files without warning! */ unsigned encode(const std::string& filename, const unsigned char* in, unsigned w, unsigned h, LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); unsigned encode(const std::string& filename, const std::vector& in, unsigned w, unsigned h, LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); #endif /* LODEPNG_COMPILE_DISK */ #endif /* LODEPNG_COMPILE_ENCODER */ } /* namespace lodepng */ #endif /*LODEPNG_COMPILE_CPP*/ #endif /*LODEPNG_COMPILE_PNG*/ #ifdef LODEPNG_COMPILE_ERROR_TEXT /*Returns an English description of the numerical error code.*/ const char* lodepng_error_text(unsigned code); #endif /*LODEPNG_COMPILE_ERROR_TEXT*/ #ifdef LODEPNG_COMPILE_DECODER /*Settings for zlib decompression*/ typedef struct LodePNGDecompressSettings LodePNGDecompressSettings; struct LodePNGDecompressSettings { unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/ /*use custom zlib decoder instead of built in one (default: null)*/ unsigned (*custom_zlib)(unsigned char**, size_t*, const unsigned char*, size_t, const LodePNGDecompressSettings*); /*use custom deflate decoder instead of built in one (default: null) if custom_zlib is used, custom_deflate is ignored since only the built in zlib function will call custom_deflate*/ unsigned (*custom_inflate)(unsigned char**, size_t*, const unsigned char*, size_t, const LodePNGDecompressSettings*); const void* custom_context; /*optional custom settings for custom functions*/ }; extern const LodePNGDecompressSettings lodepng_default_decompress_settings; void lodepng_decompress_settings_init(LodePNGDecompressSettings* settings); #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER /* Settings for zlib compression. Tweaking these settings tweaks the balance between speed and compression ratio. */ typedef struct LodePNGCompressSettings LodePNGCompressSettings; struct LodePNGCompressSettings /*deflate = compress*/ { /*LZ77 related settings*/ unsigned btype; /*the block type for LZ (0, 1, 2 or 3, see zlib standard). Should be 2 for proper compression.*/ unsigned use_lz77; /*whether or not to use LZ77. Should be 1 for proper compression.*/ unsigned windowsize; /*must be a power of two <= 32768. higher compresses more but is slower. Default value: 2048.*/ unsigned minmatch; /*mininum lz77 length. 3 is normally best, 6 can be better for some PNGs. Default: 0*/ unsigned nicematch; /*stop searching if >= this length found. Set to 258 for best compression. Default: 128*/ unsigned lazymatching; /*use lazy matching: better compression but a bit slower. Default: true*/ /*use custom zlib encoder instead of built in one (default: null)*/ unsigned (*custom_zlib)(unsigned char**, size_t*, const unsigned char*, size_t, const LodePNGCompressSettings*); /*use custom deflate encoder instead of built in one (default: null) if custom_zlib is used, custom_deflate is ignored since only the built in zlib function will call custom_deflate*/ unsigned (*custom_deflate)(unsigned char**, size_t*, const unsigned char*, size_t, const LodePNGCompressSettings*); const void* custom_context; /*optional custom settings for custom functions*/ }; extern const LodePNGCompressSettings lodepng_default_compress_settings; void lodepng_compress_settings_init(LodePNGCompressSettings* settings); #endif /*LODEPNG_COMPILE_ENCODER*/ #ifdef LODEPNG_COMPILE_PNG /* Color mode of an image. Contains all information required to decode the pixel bits to RGBA colors. This information is the same as used in the PNG file format, and is used both for PNG and raw image data in LodePNG. */ typedef struct LodePNGColorMode { /*header (IHDR)*/ LodePNGColorType colortype; /*color type, see PNG standard or documentation further in this header file*/ unsigned bitdepth; /*bits per sample, see PNG standard or documentation further in this header file*/ /* palette (PLTE and tRNS) Dynamically allocated with the colors of the palette, including alpha. When encoding a PNG, to store your colors in the palette of the LodePNGColorMode, first use lodepng_palette_clear, then for each color use lodepng_palette_add. If you encode an image without alpha with palette, don't forget to put value 255 in each A byte of the palette. When decoding, by default you can ignore this palette, since LodePNG already fills the palette colors in the pixels of the raw RGBA output. The palette is only supported for color type 3. */ unsigned char* palette; /*palette in RGBARGBA... order. When allocated, must be either 0, or have size 1024*/ size_t palettesize; /*palette size in number of colors (amount of bytes is 4 * palettesize)*/ /* transparent color key (tRNS) This color uses the same bit depth as the bitdepth value in this struct, which can be 1-bit to 16-bit. For greyscale PNGs, r, g and b will all 3 be set to the same. When decoding, by default you can ignore this information, since LodePNG sets pixels with this key to transparent already in the raw RGBA output. The color key is only supported for color types 0 and 2. */ unsigned key_defined; /*is a transparent color key given? 0 = false, 1 = true*/ unsigned key_r; /*red/greyscale component of color key*/ unsigned key_g; /*green component of color key*/ unsigned key_b; /*blue component of color key*/ } LodePNGColorMode; /*init, cleanup and copy functions to use with this struct*/ void lodepng_color_mode_init(LodePNGColorMode* info); void lodepng_color_mode_cleanup(LodePNGColorMode* info); /*return value is error code (0 means no error)*/ unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* source); void lodepng_palette_clear(LodePNGColorMode* info); /*add 1 color to the palette*/ unsigned lodepng_palette_add(LodePNGColorMode* info, unsigned char r, unsigned char g, unsigned char b, unsigned char a); /*get the total amount of bits per pixel, based on colortype and bitdepth in the struct*/ unsigned lodepng_get_bpp(const LodePNGColorMode* info); /*get the amount of color channels used, based on colortype in the struct. If a palette is used, it counts as 1 channel.*/ unsigned lodepng_get_channels(const LodePNGColorMode* info); /*is it a greyscale type? (only colortype 0 or 4)*/ unsigned lodepng_is_greyscale_type(const LodePNGColorMode* info); /*has it got an alpha channel? (only colortype 2 or 6)*/ unsigned lodepng_is_alpha_type(const LodePNGColorMode* info); /*has it got a palette? (only colortype 3)*/ unsigned lodepng_is_palette_type(const LodePNGColorMode* info); /*only returns true if there is a palette and there is a value in the palette with alpha < 255. Loops through the palette to check this.*/ unsigned lodepng_has_palette_alpha(const LodePNGColorMode* info); /* Check if the given color info indicates the possibility of having non-opaque pixels in the PNG image. Returns true if the image can have translucent or invisible pixels (it still be opaque if it doesn't use such pixels). Returns false if the image can only have opaque pixels. In detail, it returns true only if it's a color type with alpha, or has a palette with non-opaque values, or if "key_defined" is true. */ unsigned lodepng_can_have_alpha(const LodePNGColorMode* info); /*Returns the byte size of a raw image buffer with given width, height and color mode*/ size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* color); #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /*The information of a Time chunk in PNG.*/ typedef struct LodePNGTime { unsigned year; /*2 bytes used (0-65535)*/ unsigned month; /*1-12*/ unsigned day; /*1-31*/ unsigned hour; /*0-23*/ unsigned minute; /*0-59*/ unsigned second; /*0-60 (to allow for leap seconds)*/ } LodePNGTime; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ /*Information about the PNG image, except pixels, width and height.*/ typedef struct LodePNGInfo { /*header (IHDR), palette (PLTE) and transparency (tRNS) chunks*/ unsigned compression_method;/*compression method of the original file. Always 0.*/ unsigned filter_method; /*filter method of the original file*/ unsigned interlace_method; /*interlace method of the original file*/ LodePNGColorMode color; /*color type and bits, palette and transparency of the PNG file*/ #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /* suggested background color chunk (bKGD) This color uses the same color mode as the PNG (except alpha channel), which can be 1-bit to 16-bit. For greyscale PNGs, r, g and b will all 3 be set to the same. When encoding the encoder writes the red one. For palette PNGs: When decoding, the RGB value will be stored, not a palette index. But when encoding, specify the index of the palette in background_r, the other two are then ignored. The decoder does not use this background color to edit the color of pixels. */ unsigned background_defined; /*is a suggested background color given?*/ unsigned background_r; /*red component of suggested background color*/ unsigned background_g; /*green component of suggested background color*/ unsigned background_b; /*blue component of suggested background color*/ /* non-international text chunks (tEXt and zTXt) The char** arrays each contain num strings. The actual messages are in text_strings, while text_keys are keywords that give a short description what the actual text represents, e.g. Title, Author, Description, or anything else. A keyword is minimum 1 character and maximum 79 characters long. It's discouraged to use a single line length longer than 79 characters for texts. Don't allocate these text buffers yourself. Use the init/cleanup functions correctly and use lodepng_add_text and lodepng_clear_text. */ size_t text_num; /*the amount of texts in these char** buffers (there may be more texts in itext)*/ char** text_keys; /*the keyword of a text chunk (e.g. "Comment")*/ char** text_strings; /*the actual text*/ /* international text chunks (iTXt) Similar to the non-international text chunks, but with additional strings "langtags" and "transkeys". */ size_t itext_num; /*the amount of international texts in this PNG*/ char** itext_keys; /*the English keyword of the text chunk (e.g. "Comment")*/ char** itext_langtags; /*language tag for this text's language, ISO/IEC 646 string, e.g. ISO 639 language tag*/ char** itext_transkeys; /*keyword translated to the international language - UTF-8 string*/ char** itext_strings; /*the actual international text - UTF-8 string*/ /*time chunk (tIME)*/ unsigned time_defined; /*set to 1 to make the encoder generate a tIME chunk*/ LodePNGTime time; /*phys chunk (pHYs)*/ unsigned phys_defined; /*if 0, there is no pHYs chunk and the values below are undefined, if 1 else there is one*/ unsigned phys_x; /*pixels per unit in x direction*/ unsigned phys_y; /*pixels per unit in y direction*/ unsigned phys_unit; /*may be 0 (unknown unit) or 1 (metre)*/ /* unknown chunks There are 3 buffers, one for each position in the PNG where unknown chunks can appear each buffer contains all unknown chunks for that position consecutively The 3 buffers are the unknown chunks between certain critical chunks: 0: IHDR-PLTE, 1: PLTE-IDAT, 2: IDAT-IEND Do not allocate or traverse this data yourself. Use the chunk traversing functions declared later, such as lodepng_chunk_next and lodepng_chunk_append, to read/write this struct. */ unsigned char* unknown_chunks_data[3]; size_t unknown_chunks_size[3]; /*size in bytes of the unknown chunks, given for protection*/ #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } LodePNGInfo; /*init, cleanup and copy functions to use with this struct*/ void lodepng_info_init(LodePNGInfo* info); void lodepng_info_cleanup(LodePNGInfo* info); /*return value is error code (0 means no error)*/ unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source); #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/ unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str); /*push back both texts at once*/ void lodepng_clear_itext(LodePNGInfo* info); /*use this to clear the itexts again after you filled them in*/ unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag, const char* transkey, const char* str); /*push back the 4 texts of 1 chunk at once*/ #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ /* Converts raw buffer from one color type to another color type, based on LodePNGColorMode structs to describe the input and output color type. See the reference manual at the end of this header file to see which color conversions are supported. return value = LodePNG error code (0 if all went ok, an error if the conversion isn't supported) The out buffer must have size (w * h * bpp + 7) / 8, where bpp is the bits per pixel of the output color type (lodepng_get_bpp). For < 8 bpp images, there should not be padding bits at the end of scanlines. For 16-bit per channel colors, uses big endian format like PNG does. Return value is LodePNG error code */ unsigned lodepng_convert(unsigned char* out, const unsigned char* in, const LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, unsigned w, unsigned h); #ifdef LODEPNG_COMPILE_DECODER /* Settings for the decoder. This contains settings for the PNG and the Zlib decoder, but not the Info settings from the Info structs. */ typedef struct LodePNGDecoderSettings { LodePNGDecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/ unsigned ignore_crc; /*ignore CRC checksums*/ unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/ #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS unsigned read_text_chunks; /*if false but remember_unknown_chunks is true, they're stored in the unknown chunks*/ /*store all bytes from unknown chunks in the LodePNGInfo (off by default, useful for a png editor)*/ unsigned remember_unknown_chunks; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } LodePNGDecoderSettings; void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings); #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER /*automatically use color type with less bits per pixel if losslessly possible. Default: AUTO*/ typedef enum LodePNGFilterStrategy { /*every filter at zero*/ LFS_ZERO, /*Use filter that gives minimum sum, as described in the official PNG filter heuristic.*/ LFS_MINSUM, /*Use the filter type that gives smallest Shannon entropy for this scanline. Depending on the image, this is better or worse than minsum.*/ LFS_ENTROPY, /* Brute-force-search PNG filters by compressing each filter for each scanline. Experimental, very slow, and only rarely gives better compression than MINSUM. */ LFS_BRUTE_FORCE, /*use predefined_filters buffer: you specify the filter type for each scanline*/ LFS_PREDEFINED } LodePNGFilterStrategy; /*Gives characteristics about the colors of the image, which helps decide which color model to use for encoding. Used internally by default if "auto_convert" is enabled. Public because it's useful for custom algorithms.*/ typedef struct LodePNGColorProfile { unsigned colored; /*not greyscale*/ unsigned key; /*if true, image is not opaque. Only if true and alpha is false, color key is possible.*/ unsigned short key_r; /*these values are always in 16-bit bitdepth in the profile*/ unsigned short key_g; unsigned short key_b; unsigned alpha; /*alpha channel or alpha palette required*/ unsigned numcolors; /*amount of colors, up to 257. Not valid if bits == 16.*/ unsigned char palette[1024]; /*Remembers up to the first 256 RGBA colors, in no particular order*/ unsigned bits; /*bits per channel (not for palette). 1,2 or 4 for greyscale only. 16 if 16-bit per channel required.*/ } LodePNGColorProfile; void lodepng_color_profile_init(LodePNGColorProfile* profile); /*Get a LodePNGColorProfile of the image.*/ unsigned lodepng_get_color_profile(LodePNGColorProfile* profile, const unsigned char* image, unsigned w, unsigned h, const LodePNGColorMode* mode_in); /*The function LodePNG uses internally to decide the PNG color with auto_convert. Chooses an optimal color model, e.g. grey if only grey pixels, palette if < 256 colors, ...*/ unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out, const unsigned char* image, unsigned w, unsigned h, const LodePNGColorMode* mode_in); /*Settings for the encoder.*/ typedef struct LodePNGEncoderSettings { LodePNGCompressSettings zlibsettings; /*settings for the zlib encoder, such as window size, ...*/ unsigned auto_convert; /*automatically choose output PNG color type. Default: true*/ /*If true, follows the official PNG heuristic: if the PNG uses a palette or lower than 8 bit depth, set all filters to zero. Otherwise use the filter_strategy. Note that to completely follow the official PNG heuristic, filter_palette_zero must be true and filter_strategy must be LFS_MINSUM*/ unsigned filter_palette_zero; /*Which filter strategy to use when not using zeroes due to filter_palette_zero. Set filter_palette_zero to 0 to ensure always using your chosen strategy. Default: LFS_MINSUM*/ LodePNGFilterStrategy filter_strategy; /*used if filter_strategy is LFS_PREDEFINED. In that case, this must point to a buffer with the same length as the amount of scanlines in the image, and each value must <= 5. You have to cleanup this buffer, LodePNG will never free it. Don't forget that filter_palette_zero must be set to 0 to ensure this is also used on palette or low bitdepth images.*/ const unsigned char* predefined_filters; /*force creating a PLTE chunk if colortype is 2 or 6 (= a suggested palette). If colortype is 3, PLTE is _always_ created.*/ unsigned force_palette; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /*add LodePNG identifier and version as a text chunk, for debugging*/ unsigned add_id; /*encode text chunks as zTXt chunks instead of tEXt chunks, and use compression in iTXt chunks*/ unsigned text_compression; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } LodePNGEncoderSettings; void lodepng_encoder_settings_init(LodePNGEncoderSettings* settings); #endif /*LODEPNG_COMPILE_ENCODER*/ #if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) /*The settings, state and information for extended encoding and decoding.*/ typedef struct LodePNGState { #ifdef LODEPNG_COMPILE_DECODER LodePNGDecoderSettings decoder; /*the decoding settings*/ #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER LodePNGEncoderSettings encoder; /*the encoding settings*/ #endif /*LODEPNG_COMPILE_ENCODER*/ LodePNGColorMode info_raw; /*specifies the format in which you would like to get the raw pixel buffer*/ LodePNGInfo info_png; /*info of the PNG image obtained after decoding*/ unsigned error; #ifdef LODEPNG_COMPILE_CPP /* For the lodepng::State subclass. */ virtual ~LodePNGState(){} #endif } LodePNGState; /*init, cleanup and copy functions to use with this struct*/ void lodepng_state_init(LodePNGState* state); void lodepng_state_cleanup(LodePNGState* state); void lodepng_state_copy(LodePNGState* dest, const LodePNGState* source); #endif /* defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) */ #ifdef LODEPNG_COMPILE_DECODER /* Same as lodepng_decode_memory, but uses a LodePNGState to allow custom settings and getting much more information about the PNG image and color mode. */ unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h, LodePNGState* state, const unsigned char* in, size_t insize); /* Read the PNG header, but not the actual data. This returns only the information that is in the header chunk of the PNG, such as width, height and color type. The information is placed in the info_png field of the LodePNGState. */ unsigned lodepng_inspect(unsigned* w, unsigned* h, LodePNGState* state, const unsigned char* in, size_t insize); #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER /*This function allocates the out buffer with standard malloc and stores the size in *outsize.*/ unsigned lodepng_encode(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h, LodePNGState* state); #endif /*LODEPNG_COMPILE_ENCODER*/ /* The lodepng_chunk functions are normally not needed, except to traverse the unknown chunks stored in the LodePNGInfo struct, or add new ones to it. It also allows traversing the chunks of an encoded PNG file yourself. PNG standard chunk naming conventions: First byte: uppercase = critical, lowercase = ancillary Second byte: uppercase = public, lowercase = private Third byte: must be uppercase Fourth byte: uppercase = unsafe to copy, lowercase = safe to copy */ /* Gets the length of the data of the chunk. Total chunk length has 12 bytes more. There must be at least 4 bytes to read from. If the result value is too large, it may be corrupt data. */ unsigned lodepng_chunk_length(const unsigned char* chunk); /*puts the 4-byte type in null terminated string*/ void lodepng_chunk_type(char type[5], const unsigned char* chunk); /*check if the type is the given type*/ unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type); /*0: it's one of the critical chunk types, 1: it's an ancillary chunk (see PNG standard)*/ unsigned char lodepng_chunk_ancillary(const unsigned char* chunk); /*0: public, 1: private (see PNG standard)*/ unsigned char lodepng_chunk_private(const unsigned char* chunk); /*0: the chunk is unsafe to copy, 1: the chunk is safe to copy (see PNG standard)*/ unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk); /*get pointer to the data of the chunk, where the input points to the header of the chunk*/ unsigned char* lodepng_chunk_data(unsigned char* chunk); const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk); /*returns 0 if the crc is correct, 1 if it's incorrect (0 for OK as usual!)*/ unsigned lodepng_chunk_check_crc(const unsigned char* chunk); /*generates the correct CRC from the data and puts it in the last 4 bytes of the chunk*/ void lodepng_chunk_generate_crc(unsigned char* chunk); /*iterate to next chunks. don't use on IEND chunk, as there is no next chunk then*/ unsigned char* lodepng_chunk_next(unsigned char* chunk); const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk); /* Appends chunk to the data in out. The given chunk should already have its chunk header. The out variable and outlength are updated to reflect the new reallocated buffer. Returns error code (0 if it went ok) */ unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsigned char* chunk); /* Appends new chunk to out. The chunk to append is given by giving its length, type and data separately. The type is a 4-letter string. The out variable and outlength are updated to reflect the new reallocated buffer. Returne error code (0 if it went ok) */ unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length, const char* type, const unsigned char* data); /*Calculate CRC32 of buffer*/ unsigned lodepng_crc32(const unsigned char* buf, size_t len); #endif /*LODEPNG_COMPILE_PNG*/ #ifdef LODEPNG_COMPILE_ZLIB /* This zlib part can be used independently to zlib compress and decompress a buffer. It cannot be used to create gzip files however, and it only supports the part of zlib that is required for PNG, it does not support dictionaries. */ #ifdef LODEPNG_COMPILE_DECODER /*Inflate a buffer. Inflate is the decompression step of deflate. Out buffer must be freed after use.*/ unsigned lodepng_inflate(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings); /* Decompresses Zlib data. Reallocates the out buffer and appends the data. The data must be according to the zlib specification. Either, *out must be NULL and *outsize must be 0, or, *out must be a valid buffer and *outsize its size in bytes. out must be freed by user after usage. */ unsigned lodepng_zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings); #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER /* Compresses data with Zlib. Reallocates the out buffer and appends the data. Zlib adds a small header and trailer around the deflate data. The data is output in the format of the zlib specification. Either, *out must be NULL and *outsize must be 0, or, *out must be a valid buffer and *outsize its size in bytes. out must be freed by user after usage. */ unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGCompressSettings* settings); /* Find length-limited Huffman code for given frequencies. This function is in the public interface only for tests, it's used internally by lodepng_deflate. */ unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies, size_t numcodes, unsigned maxbitlen); /*Compress a buffer with deflate. See RFC 1951. Out buffer must be freed after use.*/ unsigned lodepng_deflate(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGCompressSettings* settings); #endif /*LODEPNG_COMPILE_ENCODER*/ #endif /*LODEPNG_COMPILE_ZLIB*/ #ifdef LODEPNG_COMPILE_DISK /* Load a file from disk into buffer. The function allocates the out buffer, and after usage you should free it. out: output parameter, contains pointer to loaded buffer. outsize: output parameter, size of the allocated out buffer filename: the path to the file to load return value: error code (0 means ok) */ unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename); /* Save a file from buffer to disk. Warning, if it exists, this function overwrites the file without warning! buffer: the buffer to write buffersize: size of the buffer to write filename: the path to the file to save to return value: error code (0 means ok) */ unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename); #endif /*LODEPNG_COMPILE_DISK*/ #ifdef LODEPNG_COMPILE_CPP /* The LodePNG C++ wrapper uses std::vectors instead of manually allocated memory buffers. */ namespace lodepng { #ifdef LODEPNG_COMPILE_PNG class State : public LodePNGState { public: State(); State(const State& other); virtual ~State(); State& operator=(const State& other); }; #ifdef LODEPNG_COMPILE_DECODER /* Same as other lodepng::decode, but using a State for more settings and information. */ unsigned decode(std::vector& out, unsigned& w, unsigned& h, State& state, const unsigned char* in, size_t insize); unsigned decode(std::vector& out, unsigned& w, unsigned& h, State& state, const std::vector& in); #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER /* Same as other lodepng::encode, but using a State for more settings and information. */ unsigned encode(std::vector& out, const unsigned char* in, unsigned w, unsigned h, State& state); unsigned encode(std::vector& out, const std::vector& in, unsigned w, unsigned h, State& state); #endif /*LODEPNG_COMPILE_ENCODER*/ #ifdef LODEPNG_COMPILE_DISK /* Load a file from disk into an std::vector. return value: error code (0 means ok) */ unsigned load_file(std::vector& buffer, const std::string& filename); /* Save the binary data in an std::vector to a file on disk. The file is overwritten without warning. */ unsigned save_file(const std::vector& buffer, const std::string& filename); #endif /* LODEPNG_COMPILE_DISK */ #endif /* LODEPNG_COMPILE_PNG */ #ifdef LODEPNG_COMPILE_ZLIB #ifdef LODEPNG_COMPILE_DECODER /* Zlib-decompress an unsigned char buffer */ unsigned decompress(std::vector& out, const unsigned char* in, size_t insize, const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); /* Zlib-decompress an std::vector */ unsigned decompress(std::vector& out, const std::vector& in, const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); #endif /* LODEPNG_COMPILE_DECODER */ #ifdef LODEPNG_COMPILE_ENCODER /* Zlib-compress an unsigned char buffer */ unsigned compress(std::vector& out, const unsigned char* in, size_t insize, const LodePNGCompressSettings& settings = lodepng_default_compress_settings); /* Zlib-compress an std::vector */ unsigned compress(std::vector& out, const std::vector& in, const LodePNGCompressSettings& settings = lodepng_default_compress_settings); #endif /* LODEPNG_COMPILE_ENCODER */ #endif /* LODEPNG_COMPILE_ZLIB */ } /* namespace lodepng */ #endif /*LODEPNG_COMPILE_CPP*/ /* TODO: [.] test if there are no memory leaks or security exploits - done a lot but needs to be checked often [.] check compatibility with various compilers - done but needs to be redone for every newer version [X] converting color to 16-bit per channel types [ ] read all public PNG chunk types (but never let the color profile and gamma ones touch RGB values) [ ] make sure encoder generates no chunks with size > (2^31)-1 [ ] partial decoding (stream processing) [X] let the "isFullyOpaque" function check color keys and transparent palettes too [X] better name for the variables "codes", "codesD", "codelengthcodes", "clcl" and "lldl" [ ] don't stop decoding on errors like 69, 57, 58 (make warnings) [ ] make warnings like: oob palette, checksum fail, data after iend, wrong/unknown crit chunk, no null terminator in text, ... [ ] let the C++ wrapper catch exceptions coming from the standard library and return LodePNG error codes [ ] allow user to provide custom color conversion functions, e.g. for premultiplied alpha, padding bits or not, ... [ ] allow user to give data (void*) to custom allocator */ #endif /*LODEPNG_H inclusion guard*/ /* LodePNG Documentation --------------------- 0. table of contents -------------------- 1. about 1.1. supported features 1.2. features not supported 2. C and C++ version 3. security 4. decoding 5. encoding 6. color conversions 6.1. PNG color types 6.2. color conversions 6.3. padding bits 6.4. A note about 16-bits per channel and endianness 7. error values 8. chunks and PNG editing 9. compiler support 10. examples 10.1. decoder C++ example 10.2. decoder C example 11. state settings reference 12. changes 13. contact information 1. about -------- PNG is a file format to store raster images losslessly with good compression, supporting different color types and alpha channel. LodePNG is a PNG codec according to the Portable Network Graphics (PNG) Specification (Second Edition) - W3C Recommendation 10 November 2003. The specifications used are: *) Portable Network Graphics (PNG) Specification (Second Edition): http://www.w3.org/TR/2003/REC-PNG-20031110 *) RFC 1950 ZLIB Compressed Data Format version 3.3: http://www.gzip.org/zlib/rfc-zlib.html *) RFC 1951 DEFLATE Compressed Data Format Specification ver 1.3: http://www.gzip.org/zlib/rfc-deflate.html The most recent version of LodePNG can currently be found at http://lodev.org/lodepng/ LodePNG works both in C (ISO C90) and C++, with a C++ wrapper that adds extra functionality. LodePNG exists out of two files: -lodepng.h: the header file for both C and C++ -lodepng.c(pp): give it the name lodepng.c or lodepng.cpp (or .cc) depending on your usage If you want to start using LodePNG right away without reading this doc, get the examples from the LodePNG website to see how to use it in code, or check the smaller examples in chapter 13 here. LodePNG is simple but only supports the basic requirements. To achieve simplicity, the following design choices were made: There are no dependencies on any external library. There are functions to decode and encode a PNG with a single function call, and extended versions of these functions taking a LodePNGState struct allowing to specify or get more information. By default the colors of the raw image are always RGB or RGBA, no matter what color type the PNG file uses. To read and write files, there are simple functions to convert the files to/from buffers in memory. This all makes LodePNG suitable for loading textures in games, demos and small programs, ... It's less suitable for full fledged image editors, loading PNGs over network (it requires all the image data to be available before decoding can begin), life-critical systems, ... 1.1. supported features ----------------------- The following features are supported by the decoder: *) decoding of PNGs with any color type, bit depth and interlace mode, to a 24- or 32-bit color raw image, or the same color type as the PNG *) encoding of PNGs, from any raw image to 24- or 32-bit color, or the same color type as the raw image *) Adam7 interlace and deinterlace for any color type *) loading the image from harddisk or decoding it from a buffer from other sources than harddisk *) support for alpha channels, including RGBA color model, translucent palettes and color keying *) zlib decompression (inflate) *) zlib compression (deflate) *) CRC32 and ADLER32 checksums *) handling of unknown chunks, allowing making a PNG editor that stores custom and unknown chunks. *) the following chunks are supported (generated/interpreted) by both encoder and decoder: IHDR: header information PLTE: color palette IDAT: pixel data IEND: the final chunk tRNS: transparency for palettized images tEXt: textual information zTXt: compressed textual information iTXt: international textual information bKGD: suggested background color pHYs: physical dimensions tIME: modification time 1.2. features not supported --------------------------- The following features are _not_ supported: *) some features needed to make a conformant PNG-Editor might be still missing. *) partial loading/stream processing. All data must be available and is processed in one call. *) The following public chunks are not supported but treated as unknown chunks by LodePNG cHRM, gAMA, iCCP, sRGB, sBIT, hIST, sPLT Some of these are not supported on purpose: LodePNG wants to provide the RGB values stored in the pixels, not values modified by system dependent gamma or color models. 2. C and C++ version -------------------- The C version uses buffers allocated with alloc that you need to free() yourself. You need to use init and cleanup functions for each struct whenever using a struct from the C version to avoid exploits and memory leaks. The C++ version has extra functions with std::vectors in the interface and the lodepng::State class which is a LodePNGState with constructor and destructor. These files work without modification for both C and C++ compilers because all the additional C++ code is in "#ifdef __cplusplus" blocks that make C-compilers ignore it, and the C code is made to compile both with strict ISO C90 and C++. To use the C++ version, you need to rename the source file to lodepng.cpp (instead of lodepng.c), and compile it with a C++ compiler. To use the C version, you need to rename the source file to lodepng.c (instead of lodepng.cpp), and compile it with a C compiler. 3. Security ----------- Even if carefully designed, it's always possible that LodePNG contains possible exploits. If you discover one, please let me know, and it will be fixed. When using LodePNG, care has to be taken with the C version of LodePNG, as well as the C-style structs when working with C++. The following conventions are used for all C-style structs: -if a struct has a corresponding init function, always call the init function when making a new one -if a struct has a corresponding cleanup function, call it before the struct disappears to avoid memory leaks -if a struct has a corresponding copy function, use the copy function instead of "=". The destination must also be inited already. 4. Decoding ----------- Decoding converts a PNG compressed image to a raw pixel buffer. Most documentation on using the decoder is at its declarations in the header above. For C, simple decoding can be done with functions such as lodepng_decode32, and more advanced decoding can be done with the struct LodePNGState and lodepng_decode. For C++, all decoding can be done with the various lodepng::decode functions, and lodepng::State can be used for advanced features. When using the LodePNGState, it uses the following fields for decoding: *) LodePNGInfo info_png: it stores extra information about the PNG (the input) in here *) LodePNGColorMode info_raw: here you can say what color mode of the raw image (the output) you want to get *) LodePNGDecoderSettings decoder: you can specify a few extra settings for the decoder to use LodePNGInfo info_png -------------------- After decoding, this contains extra information of the PNG image, except the actual pixels, width and height because these are already gotten directly from the decoder functions. It contains for example the original color type of the PNG image, text comments, suggested background color, etc... More details about the LodePNGInfo struct are at its declaration documentation. LodePNGColorMode info_raw ------------------------- When decoding, here you can specify which color type you want the resulting raw image to be. If this is different from the colortype of the PNG, then the decoder will automatically convert the result. This conversion always works, except if you want it to convert a color PNG to greyscale or to a palette with missing colors. By default, 32-bit color is used for the result. LodePNGDecoderSettings decoder ------------------------------ The settings can be used to ignore the errors created by invalid CRC and Adler32 chunks, and to disable the decoding of tEXt chunks. There's also a setting color_convert, true by default. If false, no conversion is done, the resulting data will be as it was in the PNG (after decompression) and you'll have to puzzle the colors of the pixels together yourself using the color type information in the LodePNGInfo. 5. Encoding ----------- Encoding converts a raw pixel buffer to a PNG compressed image. Most documentation on using the encoder is at its declarations in the header above. For C, simple encoding can be done with functions such as lodepng_encode32, and more advanced decoding can be done with the struct LodePNGState and lodepng_encode. For C++, all encoding can be done with the various lodepng::encode functions, and lodepng::State can be used for advanced features. Like the decoder, the encoder can also give errors. However it gives less errors since the encoder input is trusted, the decoder input (a PNG image that could be forged by anyone) is not trusted. When using the LodePNGState, it uses the following fields for encoding: *) LodePNGInfo info_png: here you specify how you want the PNG (the output) to be. *) LodePNGColorMode info_raw: here you say what color type of the raw image (the input) has *) LodePNGEncoderSettings encoder: you can specify a few settings for the encoder to use LodePNGInfo info_png -------------------- When encoding, you use this the opposite way as when decoding: for encoding, you fill in the values you want the PNG to have before encoding. By default it's not needed to specify a color type for the PNG since it's automatically chosen, but it's possible to choose it yourself given the right settings. The encoder will not always exactly match the LodePNGInfo struct you give, it tries as close as possible. Some things are ignored by the encoder. The encoder uses, for example, the following settings from it when applicable: colortype and bitdepth, text chunks, time chunk, the color key, the palette, the background color, the interlace method, unknown chunks, ... When encoding to a PNG with colortype 3, the encoder will generate a PLTE chunk. If the palette contains any colors for which the alpha channel is not 255 (so there are translucent colors in the palette), it'll add a tRNS chunk. LodePNGColorMode info_raw ------------------------- You specify the color type of the raw image that you give to the input here, including a possible transparent color key and palette you happen to be using in your raw image data. By default, 32-bit color is assumed, meaning your input has to be in RGBA format with 4 bytes (unsigned chars) per pixel. LodePNGEncoderSettings encoder ------------------------------ The following settings are supported (some are in sub-structs): *) auto_convert: when this option is enabled, the encoder will automatically choose the smallest possible color mode (including color key) that can encode the colors of all pixels without information loss. *) btype: the block type for LZ77. 0 = uncompressed, 1 = fixed huffman tree, 2 = dynamic huffman tree (best compression). Should be 2 for proper compression. *) use_lz77: whether or not to use LZ77 for compressed block types. Should be true for proper compression. *) windowsize: the window size used by the LZ77 encoder (1 - 32768). Has value 2048 by default, but can be set to 32768 for better, but slow, compression. *) force_palette: if colortype is 2 or 6, you can make the encoder write a PLTE chunk if force_palette is true. This can used as suggested palette to convert to by viewers that don't support more than 256 colors (if those still exist) *) add_id: add text chunk "Encoder: LodePNG " to the image. *) text_compression: default 1. If 1, it'll store texts as zTXt instead of tEXt chunks. zTXt chunks use zlib compression on the text. This gives a smaller result on large texts but a larger result on small texts (such as a single program name). It's all tEXt or all zTXt though, there's no separate setting per text yet. 6. color conversions -------------------- An important thing to note about LodePNG, is that the color type of the PNG, and the color type of the raw image, are completely independent. By default, when you decode a PNG, you get the result as a raw image in the color type you want, no matter whether the PNG was encoded with a palette, greyscale or RGBA color. And if you encode an image, by default LodePNG will automatically choose the PNG color type that gives good compression based on the values of colors and amount of colors in the image. It can be configured to let you control it instead as well, though. To be able to do this, LodePNG does conversions from one color mode to another. It can convert from almost any color type to any other color type, except the following conversions: RGB to greyscale is not supported, and converting to a palette when the palette doesn't have a required color is not supported. This is not supported on purpose: this is information loss which requires a color reduction algorithm that is beyong the scope of a PNG encoder (yes, RGB to grey is easy, but there are multiple ways if you want to give some channels more weight). By default, when decoding, you get the raw image in 32-bit RGBA or 24-bit RGB color, no matter what color type the PNG has. And by default when encoding, LodePNG automatically picks the best color model for the output PNG, and expects the input image to be 32-bit RGBA or 24-bit RGB. So, unless you want to control the color format of the images yourself, you can skip this chapter. 6.1. PNG color types -------------------- A PNG image can have many color types, ranging from 1-bit color to 64-bit color, as well as palettized color modes. After the zlib decompression and unfiltering in the PNG image is done, the raw pixel data will have that color type and thus a certain amount of bits per pixel. If you want the output raw image after decoding to have another color type, a conversion is done by LodePNG. The PNG specification gives the following color types: 0: greyscale, bit depths 1, 2, 4, 8, 16 2: RGB, bit depths 8 and 16 3: palette, bit depths 1, 2, 4 and 8 4: greyscale with alpha, bit depths 8 and 16 6: RGBA, bit depths 8 and 16 Bit depth is the amount of bits per pixel per color channel. So the total amount of bits per pixel is: amount of channels * bitdepth. 6.2. color conversions ---------------------- As explained in the sections about the encoder and decoder, you can specify color types and bit depths in info_png and info_raw to change the default behaviour. If, when decoding, you want the raw image to be something else than the default, you need to set the color type and bit depth you want in the LodePNGColorMode, or the parameters colortype and bitdepth of the simple decoding function. If, when encoding, you use another color type than the default in the raw input image, you need to specify its color type and bit depth in the LodePNGColorMode of the raw image, or use the parameters colortype and bitdepth of the simple encoding function. If, when encoding, you don't want LodePNG to choose the output PNG color type but control it yourself, you need to set auto_convert in the encoder settings to false, and specify the color type you want in the LodePNGInfo of the encoder (including palette: it can generate a palette if auto_convert is true, otherwise not). If the input and output color type differ (whether user chosen or auto chosen), LodePNG will do a color conversion, which follows the rules below, and may sometimes result in an error. To avoid some confusion: -the decoder converts from PNG to raw image -the encoder converts from raw image to PNG -the colortype and bitdepth in LodePNGColorMode info_raw, are those of the raw image -the colortype and bitdepth in the color field of LodePNGInfo info_png, are those of the PNG -when encoding, the color type in LodePNGInfo is ignored if auto_convert is enabled, it is automatically generated instead -when decoding, the color type in LodePNGInfo is set by the decoder to that of the original PNG image, but it can be ignored since the raw image has the color type you requested instead -if the color type of the LodePNGColorMode and PNG image aren't the same, a conversion between the color types is done if the color types are supported. If it is not supported, an error is returned. If the types are the same, no conversion is done. -even though some conversions aren't supported, LodePNG supports loading PNGs from any colortype and saving PNGs to any colortype, sometimes it just requires preparing the raw image correctly before encoding. -both encoder and decoder use the same color converter. Non supported color conversions: -color to greyscale: no error is thrown, but the result will look ugly because only the red channel is taken -anything to palette when that palette does not have that color in it: in this case an error is thrown Supported color conversions: -anything to 8-bit RGB, 8-bit RGBA, 16-bit RGB, 16-bit RGBA -any grey or grey+alpha, to grey or grey+alpha -anything to a palette, as long as the palette has the requested colors in it -removing alpha channel -higher to smaller bitdepth, and vice versa If you want no color conversion to be done (e.g. for speed or control): -In the encoder, you can make it save a PNG with any color type by giving the raw color mode and LodePNGInfo the same color mode, and setting auto_convert to false. -In the decoder, you can make it store the pixel data in the same color type as the PNG has, by setting the color_convert setting to false. Settings in info_raw are then ignored. The function lodepng_convert does the color conversion. It is available in the interface but normally isn't needed since the encoder and decoder already call it. 6.3. padding bits ----------------- In the PNG file format, if a less than 8-bit per pixel color type is used and the scanlines have a bit amount that isn't a multiple of 8, then padding bits are used so that each scanline starts at a fresh byte. But that is NOT true for the LodePNG raw input and output. The raw input image you give to the encoder, and the raw output image you get from the decoder will NOT have these padding bits, e.g. in the case of a 1-bit image with a width of 7 pixels, the first pixel of the second scanline will the the 8th bit of the first byte, not the first bit of a new byte. 6.4. A note about 16-bits per channel and endianness ---------------------------------------------------- LodePNG uses unsigned char arrays for 16-bit per channel colors too, just like for any other color format. The 16-bit values are stored in big endian (most significant byte first) in these arrays. This is the opposite order of the little endian used by x86 CPU's. LodePNG always uses big endian because the PNG file format does so internally. Conversions to other formats than PNG uses internally are not supported by LodePNG on purpose, there are myriads of formats, including endianness of 16-bit colors, the order in which you store R, G, B and A, and so on. Supporting and converting to/from all that is outside the scope of LodePNG. This may mean that, depending on your use case, you may want to convert the big endian output of LodePNG to little endian with a for loop. This is certainly not always needed, many applications and libraries support big endian 16-bit colors anyway, but it means you cannot simply cast the unsigned char* buffer to an unsigned short* buffer on x86 CPUs. 7. error values --------------- All functions in LodePNG that return an error code, return 0 if everything went OK, or a non-zero code if there was an error. The meaning of the LodePNG error values can be retrieved with the function lodepng_error_text: given the numerical error code, it returns a description of the error in English as a string. Check the implementation of lodepng_error_text to see the meaning of each code. 8. chunks and PNG editing ------------------------- If you want to add extra chunks to a PNG you encode, or use LodePNG for a PNG editor that should follow the rules about handling of unknown chunks, or if your program is able to read other types of chunks than the ones handled by LodePNG, then that's possible with the chunk functions of LodePNG. A PNG chunk has the following layout: 4 bytes length 4 bytes type name length bytes data 4 bytes CRC 8.1. iterating through chunks ----------------------------- If you have a buffer containing the PNG image data, then the first chunk (the IHDR chunk) starts at byte number 8 of that buffer. The first 8 bytes are the signature of the PNG and are not part of a chunk. But if you start at byte 8 then you have a chunk, and can check the following things of it. NOTE: none of these functions check for memory buffer boundaries. To avoid exploits, always make sure the buffer contains all the data of the chunks. When using lodepng_chunk_next, make sure the returned value is within the allocated memory. unsigned lodepng_chunk_length(const unsigned char* chunk): Get the length of the chunk's data. The total chunk length is this length + 12. void lodepng_chunk_type(char type[5], const unsigned char* chunk): unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type): Get the type of the chunk or compare if it's a certain type unsigned char lodepng_chunk_critical(const unsigned char* chunk): unsigned char lodepng_chunk_private(const unsigned char* chunk): unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk): Check if the chunk is critical in the PNG standard (only IHDR, PLTE, IDAT and IEND are). Check if the chunk is private (public chunks are part of the standard, private ones not). Check if the chunk is safe to copy. If it's not, then, when modifying data in a critical chunk, unsafe to copy chunks of the old image may NOT be saved in the new one if your program doesn't handle that type of unknown chunk. unsigned char* lodepng_chunk_data(unsigned char* chunk): const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk): Get a pointer to the start of the data of the chunk. unsigned lodepng_chunk_check_crc(const unsigned char* chunk): void lodepng_chunk_generate_crc(unsigned char* chunk): Check if the crc is correct or generate a correct one. unsigned char* lodepng_chunk_next(unsigned char* chunk): const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk): Iterate to the next chunk. This works if you have a buffer with consecutive chunks. Note that these functions do no boundary checking of the allocated data whatsoever, so make sure there is enough data available in the buffer to be able to go to the next chunk. unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsigned char* chunk): unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length, const char* type, const unsigned char* data): These functions are used to create new chunks that are appended to the data in *out that has length *outlength. The append function appends an existing chunk to the new data. The create function creates a new chunk with the given parameters and appends it. Type is the 4-letter name of the chunk. 8.2. chunks in info_png ----------------------- The LodePNGInfo struct contains fields with the unknown chunk in it. It has 3 buffers (each with size) to contain 3 types of unknown chunks: the ones that come before the PLTE chunk, the ones that come between the PLTE and the IDAT chunks, and the ones that come after the IDAT chunks. It's necessary to make the distionction between these 3 cases because the PNG standard forces to keep the ordering of unknown chunks compared to the critical chunks, but does not force any other ordering rules. info_png.unknown_chunks_data[0] is the chunks before PLTE info_png.unknown_chunks_data[1] is the chunks after PLTE, before IDAT info_png.unknown_chunks_data[2] is the chunks after IDAT The chunks in these 3 buffers can be iterated through and read by using the same way described in the previous subchapter. When using the decoder to decode a PNG, you can make it store all unknown chunks if you set the option settings.remember_unknown_chunks to 1. By default, this option is off (0). The encoder will always encode unknown chunks that are stored in the info_png. If you need it to add a particular chunk that isn't known by LodePNG, you can use lodepng_chunk_append or lodepng_chunk_create to the chunk data in info_png.unknown_chunks_data[x]. Chunks that are known by LodePNG should not be added in that way. E.g. to make LodePNG add a bKGD chunk, set background_defined to true and add the correct parameters there instead. 9. compiler support ------------------- No libraries other than the current standard C library are needed to compile LodePNG. For the C++ version, only the standard C++ library is needed on top. Add the files lodepng.c(pp) and lodepng.h to your project, include lodepng.h where needed, and your program can read/write PNG files. It is compatible with C90 and up, and C++03 and up. If performance is important, use optimization when compiling! For both the encoder and decoder, this makes a large difference. Make sure that LodePNG is compiled with the same compiler of the same version and with the same settings as the rest of the program, or the interfaces with std::vectors and std::strings in C++ can be incompatible. CHAR_BITS must be 8 or higher, because LodePNG uses unsigned chars for octets. *) gcc and g++ LodePNG is developed in gcc so this compiler is natively supported. It gives no warnings with compiler options "-Wall -Wextra -pedantic -ansi", with gcc and g++ version 4.7.1 on Linux, 32-bit and 64-bit. *) Clang Fully supported and warning-free. *) Mingw The Mingw compiler (a port of gcc for Windows) should be fully supported by LodePNG. *) Visual Studio and Visual C++ Express Edition LodePNG should be warning-free with warning level W4. Two warnings were disabled with pragmas though: warning 4244 about implicit conversions, and warning 4996 where it wants to use a non-standard function fopen_s instead of the standard C fopen. Visual Studio may want "stdafx.h" files to be included in each source file and give an error "unexpected end of file while looking for precompiled header". This is not standard C++ and will not be added to the stock LodePNG. You can disable it for lodepng.cpp only by right clicking it, Properties, C/C++, Precompiled Headers, and set it to Not Using Precompiled Headers there. NOTE: Modern versions of VS should be fully supported, but old versions, e.g. VS6, are not guaranteed to work. *) Compilers on Macintosh LodePNG has been reported to work both with gcc and LLVM for Macintosh, both for C and C++. *) Other Compilers If you encounter problems on any compilers, feel free to let me know and I may try to fix it if the compiler is modern and standards complient. 10. examples ------------ This decoder example shows the most basic usage of LodePNG. More complex examples can be found on the LodePNG website. 10.1. decoder C++ example ------------------------- #include "lodepng.h" #include int main(int argc, char *argv[]) { const char* filename = argc > 1 ? argv[1] : "test.png"; //load and decode std::vector image; unsigned width, height; unsigned error = lodepng::decode(image, width, height, filename); //if there's an error, display it if(error) std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl; //the pixels are now in the vector "image", 4 bytes per pixel, ordered RGBARGBA..., use it as texture, draw it, ... } 10.2. decoder C example ----------------------- #include "lodepng.h" int main(int argc, char *argv[]) { unsigned error; unsigned char* image; size_t width, height; const char* filename = argc > 1 ? argv[1] : "test.png"; error = lodepng_decode32_file(&image, &width, &height, filename); if(error) printf("decoder error %u: %s\n", error, lodepng_error_text(error)); / * use image here * / free(image); return 0; } 11. state settings reference ---------------------------- A quick reference of some settings to set on the LodePNGState For decoding: state.decoder.zlibsettings.ignore_adler32: ignore ADLER32 checksums state.decoder.zlibsettings.custom_...: use custom inflate function state.decoder.ignore_crc: ignore CRC checksums state.decoder.color_convert: convert internal PNG color to chosen one state.decoder.read_text_chunks: whether to read in text metadata chunks state.decoder.remember_unknown_chunks: whether to read in unknown chunks state.info_raw.colortype: desired color type for decoded image state.info_raw.bitdepth: desired bit depth for decoded image state.info_raw....: more color settings, see struct LodePNGColorMode state.info_png....: no settings for decoder but ouput, see struct LodePNGInfo For encoding: state.encoder.zlibsettings.btype: disable compression by setting it to 0 state.encoder.zlibsettings.use_lz77: use LZ77 in compression state.encoder.zlibsettings.windowsize: tweak LZ77 windowsize state.encoder.zlibsettings.minmatch: tweak min LZ77 length to match state.encoder.zlibsettings.nicematch: tweak LZ77 match where to stop searching state.encoder.zlibsettings.lazymatching: try one more LZ77 matching state.encoder.zlibsettings.custom_...: use custom deflate function state.encoder.auto_convert: choose optimal PNG color type, if 0 uses info_png state.encoder.filter_palette_zero: PNG filter strategy for palette state.encoder.filter_strategy: PNG filter strategy to encode with state.encoder.force_palette: add palette even if not encoding to one state.encoder.add_id: add LodePNG identifier and version as a text chunk state.encoder.text_compression: use compressed text chunks for metadata state.info_raw.colortype: color type of raw input image you provide state.info_raw.bitdepth: bit depth of raw input image you provide state.info_raw: more color settings, see struct LodePNGColorMode state.info_png.color.colortype: desired color type if auto_convert is false state.info_png.color.bitdepth: desired bit depth if auto_convert is false state.info_png.color....: more color settings, see struct LodePNGColorMode state.info_png....: more PNG related settings, see struct LodePNGInfo 12. changes ----------- The version number of LodePNG is the date of the change given in the format yyyymmdd. Some changes aren't backwards compatible. Those are indicated with a (!) symbol. *) 18 apr 2016: Changed qsort to custom stable sort (for platforms w/o qsort). *) 09 apr 2016: Fixed colorkey usage detection, and better file loading (within the limits of pure C90). *) 08 dec 2015: Made load_file function return error if file can't be opened. *) 24 okt 2015: Bugfix with decoding to palette output. *) 18 apr 2015: Boundary PM instead of just package-merge for faster encoding. *) 23 aug 2014: Reduced needless memory usage of decoder. *) 28 jun 2014: Removed fix_png setting, always support palette OOB for simplicity. Made ColorProfile public. *) 09 jun 2014: Faster encoder by fixing hash bug and more zeros optimization. *) 22 dec 2013: Power of two windowsize required for optimization. *) 15 apr 2013: Fixed bug with LAC_ALPHA and color key. *) 25 mar 2013: Added an optional feature to ignore some PNG errors (fix_png). *) 11 mar 2013 (!): Bugfix with custom free. Changed from "my" to "lodepng_" prefix for the custom allocators and made it possible with a new #define to use custom ones in your project without needing to change lodepng's code. *) 28 jan 2013: Bugfix with color key. *) 27 okt 2012: Tweaks in text chunk keyword length error handling. *) 8 okt 2012 (!): Added new filter strategy (entropy) and new auto color mode. (no palette). Better deflate tree encoding. New compression tweak settings. Faster color conversions while decoding. Some internal cleanups. *) 23 sep 2012: Reduced warnings in Visual Studio a little bit. *) 1 sep 2012 (!): Removed #define's for giving custom (de)compression functions and made it work with function pointers instead. *) 23 jun 2012: Added more filter strategies. Made it easier to use custom alloc and free functions and toggle #defines from compiler flags. Small fixes. *) 6 may 2012 (!): Made plugging in custom zlib/deflate functions more flexible. *) 22 apr 2012 (!): Made interface more consistent, renaming a lot. Removed redundant C++ codec classes. Reduced amount of structs. Everything changed, but it is cleaner now imho and functionality remains the same. Also fixed several bugs and shrunk the implementation code. Made new samples. *) 6 nov 2011 (!): By default, the encoder now automatically chooses the best PNG color model and bit depth, based on the amount and type of colors of the raw image. For this, autoLeaveOutAlphaChannel replaced by auto_choose_color. *) 9 okt 2011: simpler hash chain implementation for the encoder. *) 8 sep 2011: lz77 encoder lazy matching instead of greedy matching. *) 23 aug 2011: tweaked the zlib compression parameters after benchmarking. A bug with the PNG filtertype heuristic was fixed, so that it chooses much better ones (it's quite significant). A setting to do an experimental, slow, brute force search for PNG filter types is added. *) 17 aug 2011 (!): changed some C zlib related function names. *) 16 aug 2011: made the code less wide (max 120 characters per line). *) 17 apr 2011: code cleanup. Bugfixes. Convert low to 16-bit per sample colors. *) 21 feb 2011: fixed compiling for C90. Fixed compiling with sections disabled. *) 11 dec 2010: encoding is made faster, based on suggestion by Peter Eastman to optimize long sequences of zeros. *) 13 nov 2010: added LodePNG_InfoColor_hasPaletteAlpha and LodePNG_InfoColor_canHaveAlpha functions for convenience. *) 7 nov 2010: added LodePNG_error_text function to get error code description. *) 30 okt 2010: made decoding slightly faster *) 26 okt 2010: (!) changed some C function and struct names (more consistent). Reorganized the documentation and the declaration order in the header. *) 08 aug 2010: only changed some comments and external samples. *) 05 jul 2010: fixed bug thanks to warnings in the new gcc version. *) 14 mar 2010: fixed bug where too much memory was allocated for char buffers. *) 02 sep 2008: fixed bug where it could create empty tree that linux apps could read by ignoring the problem but windows apps couldn't. *) 06 jun 2008: added more error checks for out of memory cases. *) 26 apr 2008: added a few more checks here and there to ensure more safety. *) 06 mar 2008: crash with encoding of strings fixed *) 02 feb 2008: support for international text chunks added (iTXt) *) 23 jan 2008: small cleanups, and #defines to divide code in sections *) 20 jan 2008: support for unknown chunks allowing using LodePNG for an editor. *) 18 jan 2008: support for tIME and pHYs chunks added to encoder and decoder. *) 17 jan 2008: ability to encode and decode compressed zTXt chunks added Also various fixes, such as in the deflate and the padding bits code. *) 13 jan 2008: Added ability to encode Adam7-interlaced images. Improved filtering code of encoder. *) 07 jan 2008: (!) changed LodePNG to use ISO C90 instead of C++. A C++ wrapper around this provides an interface almost identical to before. Having LodePNG be pure ISO C90 makes it more portable. The C and C++ code are together in these files but it works both for C and C++ compilers. *) 29 dec 2007: (!) changed most integer types to unsigned int + other tweaks *) 30 aug 2007: bug fixed which makes this Borland C++ compatible *) 09 aug 2007: some VS2005 warnings removed again *) 21 jul 2007: deflate code placed in new namespace separate from zlib code *) 08 jun 2007: fixed bug with 2- and 4-bit color, and small interlaced images *) 04 jun 2007: improved support for Visual Studio 2005: crash with accessing invalid std::vector element [0] fixed, and level 3 and 4 warnings removed *) 02 jun 2007: made the encoder add a tag with version by default *) 27 may 2007: zlib and png code separated (but still in the same file), simple encoder/decoder functions added for more simple usage cases *) 19 may 2007: minor fixes, some code cleaning, new error added (error 69), moved some examples from here to lodepng_examples.cpp *) 12 may 2007: palette decoding bug fixed *) 24 apr 2007: changed the license from BSD to the zlib license *) 11 mar 2007: very simple addition: ability to encode bKGD chunks. *) 04 mar 2007: (!) tEXt chunk related fixes, and support for encoding palettized PNG images. Plus little interface change with palette and texts. *) 03 mar 2007: Made it encode dynamic Huffman shorter with repeat codes. Fixed a bug where the end code of a block had length 0 in the Huffman tree. *) 26 feb 2007: Huffman compression with dynamic trees (BTYPE 2) now implemented and supported by the encoder, resulting in smaller PNGs at the output. *) 27 jan 2007: Made the Adler-32 test faster so that a timewaste is gone. *) 24 jan 2007: gave encoder an error interface. Added color conversion from any greyscale type to 8-bit greyscale with or without alpha. *) 21 jan 2007: (!) Totally changed the interface. It allows more color types to convert to and is more uniform. See the manual for how it works now. *) 07 jan 2007: Some cleanup & fixes, and a few changes over the last days: encode/decode custom tEXt chunks, separate classes for zlib & deflate, and at last made the decoder give errors for incorrect Adler32 or Crc. *) 01 jan 2007: Fixed bug with encoding PNGs with less than 8 bits per channel. *) 29 dec 2006: Added support for encoding images without alpha channel, and cleaned out code as well as making certain parts faster. *) 28 dec 2006: Added "Settings" to the encoder. *) 26 dec 2006: The encoder now does LZ77 encoding and produces much smaller files now. Removed some code duplication in the decoder. Fixed little bug in an example. *) 09 dec 2006: (!) Placed output parameters of public functions as first parameter. Fixed a bug of the decoder with 16-bit per color. *) 15 okt 2006: Changed documentation structure *) 09 okt 2006: Encoder class added. It encodes a valid PNG image from the given image buffer, however for now it's not compressed. *) 08 sep 2006: (!) Changed to interface with a Decoder class *) 30 jul 2006: (!) LodePNG_InfoPng , width and height are now retrieved in different way. Renamed decodePNG to decodePNGGeneric. *) 29 jul 2006: (!) Changed the interface: image info is now returned as a struct of type LodePNG::LodePNG_Info, instead of a vector, which was a bit clumsy. *) 28 jul 2006: Cleaned the code and added new error checks. Corrected terminology "deflate" into "inflate". *) 23 jun 2006: Added SDL example in the documentation in the header, this example allows easy debugging by displaying the PNG and its transparency. *) 22 jun 2006: (!) Changed way to obtain error value. Added loadFile function for convenience. Made decodePNG32 faster. *) 21 jun 2006: (!) Changed type of info vector to unsigned. Changed position of palette in info vector. Fixed an important bug that happened on PNGs with an uncompressed block. *) 16 jun 2006: Internally changed unsigned into unsigned where needed, and performed some optimizations. *) 07 jun 2006: (!) Renamed functions to decodePNG and placed them in LodePNG namespace. Changed the order of the parameters. Rewrote the documentation in the header. Renamed files to lodepng.cpp and lodepng.h *) 22 apr 2006: Optimized and improved some code *) 07 sep 2005: (!) Changed to std::vector interface *) 12 aug 2005: Initial release (C++, decoder only) 13. contact information ----------------------- Feel free to contact me with suggestions, problems, comments, ... concerning LodePNG. If you encounter a PNG image that doesn't work properly with this decoder, feel free to send it and I'll use it to find and fix the problem. My email address is (puzzle the account and domain together with an @ symbol): Domain: gmail dot com. Account: lode dot vandevenne. Copyright (c) 2005-2016 Lode Vandevenne */ libtcod-1.6.4+dfsg/src/sys.cpp000066400000000000000000000144751321276576200162200ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #ifdef TCOD_OSUTIL_SUPPORT void TCODSystem::sleepMilli(uint32_t milliseconds) { TCOD_sys_sleep_milli(milliseconds); } uint32_t TCODSystem::getElapsedMilli() { return TCOD_sys_elapsed_milli(); } float TCODSystem::getElapsedSeconds() { return TCOD_sys_elapsed_seconds(); } #endif #ifdef TCOD_SDL2 void TCODSystem::saveScreenshot(const char *filename) { TCOD_sys_save_screenshot(filename); } void TCODSystem::forceFullscreenResolution(int width, int height) { TCOD_sys_force_fullscreen_resolution(width, height); } void TCODSystem::setRenderer(TCOD_renderer_t renderer) { TCOD_sys_set_renderer(renderer); } TCOD_event_t TCODSystem::waitForEvent(int eventMask, TCOD_key_t *key, TCOD_mouse_t *mouse, bool flush) { return TCOD_sys_wait_for_event(eventMask,key,mouse,flush); } TCOD_event_t TCODSystem::checkForEvent(int eventMask, TCOD_key_t *key, TCOD_mouse_t *mouse) { return TCOD_sys_check_for_event(eventMask,key,mouse); } TCOD_renderer_t TCODSystem::getRenderer() { return TCOD_sys_get_renderer(); } #endif #ifdef TCOD_OSUTIL_SUPPORT void TCODSystem::setFps(int val) { TCOD_sys_set_fps(val); } int TCODSystem::getFps() { return TCOD_sys_get_fps(); } float TCODSystem::getLastFrameLength() { return TCOD_sys_get_last_frame_length(); } #endif #ifdef TCOD_SDL2 void TCODSystem::getCurrentResolution(int *w, int *h) { TCOD_sys_get_current_resolution(w, h); } void TCODSystem::getFullscreenOffsets(int *offx, int *offy) { TCOD_sys_get_fullscreen_offsets(offx, offy); } void TCODSystem::updateChar(int asciiCode, int fontx, int fonty,const TCODImage *img,int x,int y) { TCOD_sys_update_char(asciiCode,fontx,fonty,img->data,x,y); } void TCODSystem::getCharSize(int *w, int *h) { TCOD_sys_get_char_size(w, h); } #endif // filesystem stuff bool TCODSystem::createDirectory(const char *path) { return TCOD_sys_create_directory(path) != 0; } bool TCODSystem::deleteFile(const char *path) { return TCOD_sys_delete_file(path) != 0; } bool TCODSystem::deleteDirectory(const char *path) { return TCOD_sys_delete_directory(path) != 0; } bool TCODSystem::isDirectory(const char *path) { return TCOD_sys_is_directory(path) != 0; } TCOD_list_t TCODSystem::getDirectoryContent(const char *path, const char *pattern) { return TCOD_sys_get_directory_content(path,pattern); } bool TCODSystem::fileExists(const char * filename, ...) { FILE * in; bool ret = false; char f[1024]; va_list ap; va_start(ap,filename); vsprintf(f,filename,ap); va_end(ap); in = fopen(f,"rb"); if (in != NULL) { ret = true; fclose(in); } return ret; } bool TCODSystem::readFile(const char *filename, unsigned char **buf, size_t *size) { return TCOD_sys_read_file(filename,buf,size) != 0; } bool TCODSystem::writeFile(const char *filename, unsigned char *buf, uint32_t size) { return TCOD_sys_write_file(filename,buf,size) != 0; } #ifdef TCOD_SDL2 // clipboard stuff bool TCODSystem::setClipboard(const char *value) { return TCOD_sys_clipboard_set(value) != 0; } char *TCODSystem::getClipboard() { return TCOD_sys_clipboard_get(); } #endif // thread stuff int TCODSystem::getNumCores() { return TCOD_sys_get_num_cores(); } TCOD_thread_t TCODSystem::newThread(int (*func)(void *), void *data) { return TCOD_thread_new(func,data); } void TCODSystem::deleteThread(TCOD_thread_t th) { TCOD_thread_delete(th); } void TCODSystem::waitThread(TCOD_thread_t th) { TCOD_thread_wait(th); } // mutex TCOD_mutex_t TCODSystem::newMutex() { return TCOD_mutex_new(); } void TCODSystem::mutexIn(TCOD_mutex_t mut) { TCOD_mutex_in(mut); } void TCODSystem::mutexOut(TCOD_mutex_t mut) { TCOD_mutex_out(mut); } void TCODSystem::deleteMutex(TCOD_mutex_t mut) { TCOD_mutex_delete(mut); } // semaphore TCOD_semaphore_t TCODSystem::newSemaphore(int initVal) { return TCOD_semaphore_new(initVal); } void TCODSystem::lockSemaphore(TCOD_semaphore_t sem) { TCOD_semaphore_lock(sem); } void TCODSystem::unlockSemaphore(TCOD_semaphore_t sem) { TCOD_semaphore_unlock(sem); } void TCODSystem::deleteSemaphore( TCOD_semaphore_t sem) { TCOD_semaphore_delete(sem); } // condition TCOD_cond_t TCODSystem::newCondition() { return TCOD_condition_new(); } void TCODSystem::signalCondition(TCOD_cond_t cond) { TCOD_condition_signal(cond); } void TCODSystem::broadcastCondition(TCOD_cond_t cond) { TCOD_condition_broadcast(cond); } void TCODSystem::waitCondition(TCOD_cond_t cond, TCOD_mutex_t mut) { TCOD_condition_wait(cond, mut); } void TCODSystem::deleteCondition( TCOD_cond_t cond) { TCOD_condition_delete(cond); } // custom post-renderer static ITCODSDLRenderer *renderer=NULL; extern "C" void TCOD_CRenderer(void *sdl_surface) { if ( renderer ) renderer->render(sdl_surface); } void TCODSystem::registerSDLRenderer(ITCODSDLRenderer *renderer) { ::renderer = renderer; #ifdef TCOD_SDL2 TCOD_sys_register_SDL_renderer(TCOD_CRenderer); #endif } libtcod-1.6.4+dfsg/src/sys_c.c000066400000000000000000000342741321276576200161610ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #if defined (__APPLE__) && defined (__MACH__) /* Is this necessary now the custom clipboard stuff is gone? */ #include #endif #include "libtcod_int.h" #include "libtcod_version.h" #ifdef TCOD_WINDOWS #include #else #include #include #include #include #include #include #include #include #endif #if defined(TCOD_WINDOWS) char *strcasestr (const char *haystack, const char *needle) { const char *p, *startn = 0, *np = 0; for (p = haystack; *p; p++) { if (np) { if (toupper(*p) == toupper(*np)) { if (!*++np) return (char *)startn; } else np = 0; } else if (toupper(*p) == toupper(*needle)) { np = needle + 1; startn = p; } } return 0; } #endif #ifdef TCOD_SDL2 void TCOD_sys_get_fullscreen_offsets(int *offx, int *offy) { if ( offx ) *offx = TCOD_ctx.fullscreen_offsetx; if ( offy ) *offy = TCOD_ctx.fullscreen_offsety; } #endif bool TCOD_sys_create_directory(const char *path) { #ifdef TCOD_WINDOWS return (CreateDirectory(path,NULL) != 0 || GetLastError() == ERROR_ALREADY_EXISTS); #else return mkdir(path,0755) == 0 || errno == EEXIST; #endif } bool TCOD_sys_delete_file(const char *path) { #ifdef TCOD_WINDOWS return DeleteFile(path) != 0; #else return unlink(path) == 0 || errno == ENOENT; #endif } bool TCOD_sys_delete_directory(const char *path) { #ifdef TCOD_WINDOWS return RemoveDirectory(path) != 0; #else return rmdir(path) == 0 || errno == ENOENT; #endif } bool TCOD_sys_is_directory(const char *path) { #ifdef TCOD_WINDOWS DWORD type=GetFileAttributes(path); return ( type & FILE_ATTRIBUTE_DIRECTORY) != 0 ; #else DIR *d=opendir(path); if ( d ) { closedir(d); return true; } return false; #endif } static bool filename_match(const char *name, const char *pattern) { char *ptr; if ( pattern == NULL || pattern[0] == 0 ) return true; ptr=strchr(pattern,'*'); if ( ! ptr ) return strcmp(name,pattern) == 0; if ( ptr != name && strncmp(name,pattern, ptr - pattern) != 0 ) return false; return strcmp( name + strlen(name) - strlen(ptr+1), ptr+1) == 0; } TCOD_list_t TCOD_sys_get_directory_content(const char *path, const char *pattern) { TCOD_list_t list=TCOD_list_new(); #ifdef TCOD_WINDOWS WIN32_FIND_DATA FileData; HANDLE hList; char dname[ 512 ]; sprintf(dname, "%s\\*",path); hList = FindFirstFile(dname, &FileData); if (hList == INVALID_HANDLE_VALUE) { return list; } do { if ( ! (strcmp(FileData.cFileName,".") == 0 || strcmp(FileData.cFileName,"..") == 0 ) ) { if ( filename_match(FileData.cFileName,pattern) ) TCOD_list_push(list,TCOD_strdup(FileData.cFileName)); } } while ( FindNextFile(hList, &FileData) ); FindClose(hList); #else DIR *dir = opendir(path); struct dirent *dirent = NULL; if ( ! dir ) return list; while ( ( dirent = readdir(dir) ) ) { if ( ! (strcmp(dirent->d_name,".") == 0 || strcmp(dirent->d_name,"..") == 0 ) ) { if ( filename_match(dirent->d_name,pattern) ) TCOD_list_push(list,strdup(dirent->d_name)); } } closedir(dir); #endif return list; } /* thread stuff */ #ifdef TCOD_WINDOWS /* Helper function to count set bits in the processor mask. */ static DWORD CountSetBits(ULONG_PTR bitMask) { DWORD LSHIFT = sizeof(ULONG_PTR)*8 - 1; DWORD bitSetCount = 0; ULONG_PTR bitTest = (ULONG_PTR)1 << LSHIFT; DWORD i; for (i = 0; i <= LSHIFT; ++i) { bitSetCount += ((bitMask & bitTest)?1:0); bitTest/=2; } return bitSetCount; } #endif int TCOD_sys_get_num_cores(void) { #ifdef TCOD_WINDOWS /* what a crap !!! works only on xp sp3 & vista */ typedef enum _PROCESSOR_CACHE_TYPE { CacheUnified, CacheInstruction, CacheData, CacheTrace } PROCESSOR_CACHE_TYPE; typedef struct _CACHE_DESCRIPTOR { BYTE Level; BYTE Associativity; WORD LineSize; DWORD Size; PROCESSOR_CACHE_TYPE Type; } CACHE_DESCRIPTOR; typedef enum _LOGICAL_PROCESSOR_RELATIONSHIP { RelationProcessorCore, RelationNumaNode, RelationCache, RelationProcessorPackage } LOGICAL_PROCESSOR_RELATIONSHIP; typedef struct _SYSTEM_LOGICAL_PROCESSOR_INFORMATION { ULONG_PTR ProcessorMask; LOGICAL_PROCESSOR_RELATIONSHIP Relationship; union { struct { BYTE Flags; } ProcessorCore; struct { DWORD NodeNumber; } NumaNode; CACHE_DESCRIPTOR Cache; ULONGLONG Reserved[2]; }; } SYSTEM_LOGICAL_PROCESSOR_INFORMATION, *PSYSTEM_LOGICAL_PROCESSOR_INFORMATION; typedef BOOL (WINAPI *LPFN_GLPI)( PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD); LPFN_GLPI glpi; BOOL done = FALSE; PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL; PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = NULL; DWORD returnLength = 0; DWORD logicalProcessorCount = 0; DWORD byteOffset = 0; glpi = (LPFN_GLPI) GetProcAddress( GetModuleHandle(TEXT("kernel32")), "GetLogicalProcessorInformation"); if (! glpi) { return 1; } while (!done) { DWORD rc = glpi(buffer, &returnLength); if (FALSE == rc) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { if (buffer) free(buffer); buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc( returnLength); if (NULL == buffer) { return 1; } } else { return 1; } } else { done = TRUE; } } ptr = buffer; while (byteOffset + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= returnLength) { switch (ptr->Relationship) { case RelationProcessorCore: /* A hyperthreaded core supplies more than one logical processor. */ logicalProcessorCount += CountSetBits(ptr->ProcessorMask); break; default: break; } byteOffset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ptr++; } free(buffer); return logicalProcessorCount; #else return sysconf(_SC_NPROCESSORS_ONLN); #endif } TCOD_thread_t TCOD_thread_new(int (*func)(void *), void *data) { #ifdef TCOD_WINDOWS HANDLE ret = CreateThread(NULL,0,(DWORD (WINAPI *)( LPVOID ))func,data,0,NULL); return (TCOD_thread_t)ret; #else pthread_t id; int iret; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); iret =pthread_create(&id,&attr,(void *(*)(void *))func,data); if ( iret != 0 ) id=0; return (TCOD_thread_t)id; #endif } void TCOD_thread_delete(TCOD_thread_t th) { #ifdef TCOD_WINDOWS CloseHandle((HANDLE)th); #endif } void TCOD_thread_wait(TCOD_thread_t th) { #ifdef TCOD_WINDOWS WaitForSingleObject((HANDLE)th,INFINITE); #else pthread_t id=(pthread_t)th; pthread_join(id,NULL); #endif } TCOD_mutex_t TCOD_mutex_new() { #ifdef TCOD_WINDOWS CRITICAL_SECTION *cs = (CRITICAL_SECTION *)calloc(sizeof(CRITICAL_SECTION),1); InitializeCriticalSection(cs); return (TCOD_mutex_t)cs; #else static pthread_mutex_t tmp=PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t *mut = (pthread_mutex_t *)calloc(sizeof(pthread_mutex_t),1); *mut = tmp; return (TCOD_mutex_t)mut; #endif } void TCOD_mutex_in(TCOD_mutex_t mut) { #ifdef TCOD_WINDOWS EnterCriticalSection((CRITICAL_SECTION *)mut); #else pthread_mutex_lock((pthread_mutex_t *)mut); #endif } void TCOD_mutex_out(TCOD_mutex_t mut) { #ifdef TCOD_WINDOWS LeaveCriticalSection((CRITICAL_SECTION *)mut); #else pthread_mutex_unlock((pthread_mutex_t *)mut); #endif } void TCOD_mutex_delete(TCOD_mutex_t mut) { #ifdef TCOD_WINDOWS DeleteCriticalSection((CRITICAL_SECTION *)mut); free(mut); #else pthread_mutex_destroy((pthread_mutex_t *)mut); free(mut); #endif } TCOD_semaphore_t TCOD_semaphore_new(int initVal) { #ifdef TCOD_WINDOWS HANDLE ret = CreateSemaphore(NULL,initVal,255,NULL); return (TCOD_semaphore_t)ret; #else sem_t *ret = (sem_t *)calloc(sizeof(sem_t),1); if ( ret ) sem_init(ret,0,initVal); return (TCOD_semaphore_t) ret; #endif } void TCOD_semaphore_lock(TCOD_semaphore_t sem) { #ifdef TCOD_WINDOWS WaitForSingleObject((HANDLE)sem,INFINITE); #else if ( sem ) sem_wait((sem_t *)sem); #endif } void TCOD_semaphore_unlock(TCOD_semaphore_t sem) { #ifdef TCOD_WINDOWS ReleaseSemaphore((HANDLE)sem,1,NULL); #else if ( sem ) sem_post((sem_t *)sem); #endif } void TCOD_semaphore_delete( TCOD_semaphore_t sem) { #ifdef TCOD_WINDOWS CloseHandle((HANDLE)sem); #else if ( sem ) { sem_destroy((sem_t *)sem); free (sem); } #endif } #ifdef TCOD_WINDOWS /* poor win32 API has no thread conditions */ typedef struct { int nbSignals; int nbWaiting; TCOD_mutex_t mutex; TCOD_semaphore_t waiting; TCOD_semaphore_t waitDone; } cond_t; #endif TCOD_cond_t TCOD_condition_new(void) { #ifdef TCOD_WINDOWS cond_t *ret = (cond_t *)calloc(sizeof(cond_t),1); ret->mutex = TCOD_mutex_new(); ret->waiting = TCOD_semaphore_new(0); ret->waitDone = TCOD_semaphore_new(0); return (TCOD_cond_t)ret; #else pthread_cond_t *ret = (pthread_cond_t *)calloc(sizeof(pthread_cond_t),1); if ( ret ) pthread_cond_init(ret,NULL); return (TCOD_cond_t) ret; #endif } void TCOD_condition_signal(TCOD_cond_t pcond) { #ifdef TCOD_WINDOWS cond_t *cond=(cond_t *)pcond; if ( cond ) { TCOD_mutex_in(cond->mutex); if ( cond->nbWaiting > cond->nbSignals ) { cond->nbSignals++; TCOD_semaphore_unlock(cond->waiting); TCOD_mutex_out(cond->mutex); TCOD_semaphore_lock(cond->waitDone); } else { TCOD_mutex_out(cond->mutex); } } #else if ( pcond ) { pthread_cond_signal((pthread_cond_t *)pcond); } #endif } void TCOD_condition_broadcast(TCOD_cond_t pcond) { #ifdef TCOD_WINDOWS cond_t *cond=(cond_t *)pcond; if ( cond ) { TCOD_mutex_in(cond->mutex); if ( cond->nbWaiting > cond->nbSignals ) { int nbUnlock=cond->nbWaiting-cond->nbSignals; int i; cond->nbSignals=cond->nbWaiting; for (i=nbUnlock; i > 0; i--) { TCOD_semaphore_unlock(cond->waiting); } TCOD_mutex_out(cond->mutex); for (i=nbUnlock; i > 0; i--) { TCOD_semaphore_lock(cond->waitDone); } } else { TCOD_mutex_out(cond->mutex); } } #else if ( pcond ) { pthread_cond_broadcast((pthread_cond_t *)pcond); } #endif } void TCOD_condition_wait(TCOD_cond_t pcond, TCOD_mutex_t mut) { #ifdef TCOD_WINDOWS cond_t *cond=(cond_t *)pcond; if ( cond ) { TCOD_mutex_in(cond->mutex); cond->nbWaiting++; TCOD_mutex_out(cond->mutex); TCOD_mutex_out(mut); TCOD_semaphore_lock(cond->waiting); TCOD_mutex_in(cond->mutex); if ( cond->nbSignals > 0 ) { TCOD_semaphore_unlock(cond->waitDone); cond->nbSignals--; } cond->nbWaiting--; TCOD_mutex_out(cond->mutex); } #else if ( pcond && mut ) { pthread_cond_wait((pthread_cond_t *)pcond, (pthread_mutex_t *)mut); } #endif } void TCOD_condition_delete( TCOD_cond_t pcond) { #ifdef TCOD_WINDOWS cond_t *cond=(cond_t *)pcond; if ( cond ) { TCOD_mutex_delete(cond->mutex); TCOD_semaphore_delete(cond->waiting); TCOD_semaphore_delete(cond->waitDone); free(cond); } #else if ( pcond ) { pthread_cond_destroy((pthread_cond_t *)pcond); free (pcond); } #endif } #ifdef TCOD_BARE void TCOD_sys_startup(void) { //TCOD_ctx.max_font_chars = 256; //alloc_ascii_tables(); } void TCOD_sys_shutdown(void) { } bool TCOD_sys_read_file(const char *filename, unsigned char **buf, size_t *size) { return false; } bool TCOD_sys_write_file(const char *filename, unsigned char *buf, uint32_t size) { return false; } #endif /* TCOD_BARE */ void TCOD_fatal(const char *fmt, ...) { va_list ap; TCOD_sys_shutdown(); printf("%s\n", TCOD_STRVERSIONNAME); va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); printf("\n"); exit(1); } void TCOD_fatal_nopar(const char *msg) { TCOD_sys_shutdown(); printf("%s\n%s\n", TCOD_STRVERSIONNAME, msg); exit(1); } /* dynamic library support */ #ifdef TCOD_WINDOWS TCOD_library_t TCOD_load_library(const char *path) { return (TCOD_library_t)LoadLibrary(path); } void * TCOD_get_function_address(TCOD_library_t library, const char *function_name) { return (void *)GetProcAddress((HMODULE)library,function_name); } void TCOD_close_library(TCOD_library_t library) { FreeLibrary((HMODULE)library); } #else TCOD_library_t TCOD_load_library(const char *path) { void *l=dlopen(path,RTLD_LAZY); return (TCOD_library_t)l; } void * TCOD_get_function_address(TCOD_library_t library, const char *function_name) { return dlsym(library,(char *)function_name); } void TCOD_close_library(TCOD_library_t library) { dlclose(library); } #endif libtcod-1.6.4+dfsg/src/sys_opengl_c.c000066400000000000000000000561321321276576200175220ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This renderer is mostly copied and pasted from Antagonist's SkyFire GLSL roguelike engine */ #ifdef TCOD_SDL2 #include #include "libtcod_int.h" #include "console.h" #ifndef NO_OPENGL #include #include #include #define CHECKGL( GLcall ) \ GLcall; \ if(!_CheckGL_Error( #GLcall, __FILE__, __LINE__)) \ return false; #ifdef NDEBUG #define DBGCHECKGL(GLcall) GLcall #else #define DBGCHECKGL CHECKGL #endif typedef enum { Character, ForeCol, BackCol, ConsoleDataEnumSize } ConsoleDataEnum; /* JBR04152012 - Made Character a 4 byte value here to support extended characters like other renderers. Seems like it should be possible to make it a two byte value using GL_UNSIGNED_SHORT_5_6_5_REV in updateTex, but I can't seem to get the math right in the shader code, it always loses precision somewhere, resulting in incorrect characters. */ const int ConsoleDataAlignment[3] = {4, 3, 3 }; static const char *TCOD_con_vertex_shader = #ifndef NDEBUG "#version 110\n" #endif "uniform vec2 termsize; " "void main(void) " "{ " " gl_Position = gl_Vertex; " " gl_TexCoord[0] = gl_MultiTexCoord0; " " gl_TexCoord[0].x = gl_TexCoord[0].x*termsize.x; " " gl_TexCoord[0].y = gl_TexCoord[0].y*termsize.y; " "} " ; static const char *TCOD_con_pixel_shader = #ifndef NDEBUG "#version 110\n" #endif "uniform sampler2D font; " "uniform sampler2D term; " "uniform sampler2D termfcol; " "uniform sampler2D termbcol; " "uniform float fontw; " "uniform vec2 fontcoef; " "uniform vec2 termsize; " "uniform vec2 termcoef; " "void main(void) " "{ " " vec2 rawCoord = gl_TexCoord[0].xy; " /* varying from [0, termsize) in x and y */ " vec2 conPos = floor(rawCoord); " /* console integer position */ " vec2 pixPos = fract(rawCoord); " /* pixel offset within console position */ " pixPos = vec2(pixPos.x*fontcoef.x,pixPos.y*fontcoef.y); " /* Correct pixel offset for font tex location */ " vec2 address = vec2(conPos.x*termcoef.x,conPos.y*termcoef.y); " " address=address+vec2(0.001, 0.001); " " vec4 charvec = texture2D(term,address);" " float inchar = (charvec.r * 256.0) + (charvec.g * 256.0 * 256.0);" /* character */ " vec4 tcharfcol = texture2D(termfcol, address); " /* front color */ " vec4 tcharbcol = texture2D(termbcol, address); " /* back color */ " vec4 tchar = vec4(mod(floor(inchar),floor(fontw)),floor(inchar/fontw), 0.0, 0.0); " /* 1D index to 2D index map for character */ " gl_FragColor = texture2D(font, vec2((tchar.x*fontcoef.x),(tchar.y*fontcoef.y))+pixPos.xy); " /* magic func: finds pixel value in font file */ " gl_FragColor=gl_FragColor.a*tcharfcol+(1.0-gl_FragColor.a)*tcharbcol; " /* Coloring stage */ "} " ; bool _CheckGL_Error(const char* GLcall, const char* file, const int line) { GLenum errCode; if((errCode = glGetError())!=GL_NO_ERROR) { printf("OPENGL ERROR #%i: in file %s on line %i\n",errCode,file, line); printf("OPENGL Call: %s\n",GLcall); return false; } return true; } /* called before creating window */ void TCOD_opengl_init_attributes(void) { static bool first=true; if ( first ) { SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8); SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32 ); /* ATI driver bug : enabling this might result in red screen */ /* SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); */ first=false; } } /* console size (power of 2 and cells) */ static int POTconwidth, POTconheight, conwidth, conheight; /* programs and shaders handles */ static GLhandleARB conProgram, conVertShader, conFragShader; /* font texture handle */ static GLuint font_tex; /* font power of 2 size and pixels */ static int POTfontwidth,POTfontheight, fontwidth,fontheight; /* console data */ static GLuint Tex[ConsoleDataEnumSize]; static unsigned char *data[ConsoleDataEnumSize]; static bool dirty[ConsoleDataEnumSize]; /* extension function pointers */ static PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB=0; static PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB=0; static PFNGLSHADERSOURCEARBPROC glShaderSourceARB=0; static PFNGLCOMPILESHADERARBPROC glCompileShaderARB=0; static PFNGLGETINFOLOGARBPROC glGetInfoLogARB=0; static PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB=0; static PFNGLATTACHOBJECTARBPROC glAttachObjectARB=0; static PFNGLLINKPROGRAMARBPROC glLinkProgramARB=0; static PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB=0; static PFNGLUNIFORM2FARBPROC glUniform2fARB=0; static PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB=0; static PFNGLUNIFORM1FARBPROC glUniform1fARB=0; static PFNGLUNIFORM1IARBPROC glUniform1iARB=0; static PFNGLACTIVETEXTUREPROC glActiveTextureF=0; static SDL_GLContext glcontext; void TCOD_opengl_uninit_state() { SDL_GL_DeleteContext(glcontext); } /* call after creating window */ bool TCOD_opengl_init_state(int conw, int conh, void *font) { SDL_Surface *font_surf=(SDL_Surface *)font; SDL_PixelFormat *my_format=SDL_AllocFormat(SDL_GetWindowPixelFormat(window)); /* convert font for opengl */ uint32_t rmask, gmask, bmask, amask; SDL_Surface *temp; SDL_Surface *temp_alpha; glcontext = SDL_GL_CreateContext(window); /* check opengl extensions */ if ( TCOD_ctx.renderer == TCOD_RENDERER_GLSL ) { bool hasShader = false; const char *glexts=(const char *)glGetString(GL_EXTENSIONS); if (glexts ) { hasShader = (strstr(glexts,"GL_ARB_shader_objects") != NULL); } if (! hasShader ) { TCOD_LOG(("Missing GL_ARB_shader_objects extension. Falling back to fixed pipeline...\n")); TCOD_ctx.renderer = TCOD_RENDERER_OPENGL; } } /* set extensions functions pointers */ glCreateShaderObjectARB=(PFNGLCREATESHADEROBJECTARBPROC)SDL_GL_GetProcAddress("glCreateShaderObjectARB"); glGetObjectParameterivARB=(PFNGLGETOBJECTPARAMETERIVARBPROC)SDL_GL_GetProcAddress("glGetObjectParameterivARB"); glShaderSourceARB=(PFNGLSHADERSOURCEARBPROC)SDL_GL_GetProcAddress("glShaderSourceARB"); glCompileShaderARB=(PFNGLCOMPILESHADERARBPROC)SDL_GL_GetProcAddress("glCompileShaderARB"); glGetInfoLogARB=(PFNGLGETINFOLOGARBPROC)SDL_GL_GetProcAddress("glGetInfoLogARB"); glCreateProgramObjectARB=(PFNGLCREATEPROGRAMOBJECTARBPROC)SDL_GL_GetProcAddress("glCreateProgramObjectARB"); glAttachObjectARB=(PFNGLATTACHOBJECTARBPROC)SDL_GL_GetProcAddress("glAttachObjectARB"); glLinkProgramARB=(PFNGLLINKPROGRAMARBPROC)SDL_GL_GetProcAddress("glLinkProgramARB"); glUseProgramObjectARB=(PFNGLUSEPROGRAMOBJECTARBPROC)SDL_GL_GetProcAddress("glUseProgramObjectARB"); glUniform2fARB=(PFNGLUNIFORM2FARBPROC)SDL_GL_GetProcAddress("glUniform2fARB"); glGetUniformLocationARB=(PFNGLGETUNIFORMLOCATIONARBPROC)SDL_GL_GetProcAddress("glGetUniformLocationARB"); glUniform1fARB=(PFNGLUNIFORM1FARBPROC)SDL_GL_GetProcAddress("glUniform1fARB"); glUniform1iARB=(PFNGLUNIFORM1IARBPROC)SDL_GL_GetProcAddress("glUniform1iARB"); glActiveTextureF=(PFNGLACTIVETEXTUREPROC)SDL_GL_GetProcAddress("glActiveTexture"); /* set opengl state */ glEnable(GL_TEXTURE_2D); glClearColor(1.0f, 1.0f, 0.0f, 0.0f); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glClear( GL_COLOR_BUFFER_BIT ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); if ( TCOD_ctx.renderer == TCOD_RENDERER_GLSL ) { glOrtho(0, conw, 0, conh, -1.0f, 1.0f); glDisable (GL_BLEND); } else { glOrtho(0, conw, conh, 0.0f, -1.0f, 1.0f); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); /*#ifdef TCOD_WINDOWS */ if ( ! TCOD_ctx.fullscreen ) { /* turn vsync off in windowed mode */ typedef bool (APIENTRY *PFNWGLSWAPINTERVALFARPROC)(int); PFNWGLSWAPINTERVALFARPROC wglSwapIntervalEXT = 0; wglSwapIntervalEXT = (PFNWGLSWAPINTERVALFARPROC)SDL_GL_GetProcAddress("wglSwapIntervalEXT"); if (wglSwapIntervalEXT) wglSwapIntervalEXT(0); } /*#endif */ /* compute pot size */ conwidth=conw; conheight=conh; POTconwidth=POTconheight=1; while ( POTconwidth < conw ) POTconwidth *= 2; while ( POTconheight < conh ) POTconheight *= 2; #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif fontwidth=font_surf->w; fontheight=font_surf->h; POTfontwidth=POTfontheight=1; while ( POTfontwidth < fontwidth ) POTfontwidth *= 2; while ( POTfontheight < fontheight ) POTfontheight *= 2; SDL_SetColorKey(font_surf, 1, SDL_MapRGB(font_surf->format, 0, 0, 0)); my_format->Amask = amask; temp_alpha = SDL_ConvertSurface(font_surf, my_format, 0); SDL_FreeFormat(my_format); temp = SDL_CreateRGBSurface(SDL_SWSURFACE, POTfontwidth, POTfontheight, 32, bmask, gmask, rmask, amask); /*BGRA */ SDL_BlitSurface(temp_alpha, NULL, temp, NULL); SDL_FreeSurface(temp_alpha); CHECKGL(glGenTextures(1, &font_tex)); CHECKGL(glBindTexture(GL_TEXTURE_2D, font_tex)); SDL_LockSurface(temp); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); CHECKGL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, temp->w, temp->h, 0, GL_BGRA, GL_UNSIGNED_BYTE, temp->pixels)); SDL_UnlockSurface(temp); SDL_FreeSurface(temp); return true; } static GLhandleARB loadShader(const char *txt, GLuint type) { int success; int infologLength = 0; int charsWritten = 0; char *infoLog; GLhandleARB v = glCreateShaderObjectARB(type); glShaderSourceARB(v, 1, &txt, 0); glCompileShaderARB(v); glGetObjectParameterivARB(v, GL_COMPILE_STATUS, &success); if(success!=GL_TRUE) { /* something went wrong */ glGetObjectParameterivARB(v, GL_INFO_LOG_LENGTH,&infologLength); if(infologLength>0) { infoLog = (char *)malloc(infologLength); glGetInfoLogARB(v, infologLength, &charsWritten, infoLog); printf("GLSL ERROR : %s\n",infoLog); free(infoLog); } return 0; } return v; } static bool loadProgram(const char *vertShaderCode, const char *fragShaderCode, GLhandleARB *vertShader, GLhandleARB *fragShader, GLhandleARB *prog) { /* Create and load Program and Shaders */ int success; *prog = DBGCHECKGL(glCreateProgramObjectARB()); *vertShader = loadShader(vertShaderCode, GL_VERTEX_SHADER); if ( *vertShader == 0 ) return false; glAttachObjectARB(*prog, *vertShader); *fragShader = loadShader(fragShaderCode, GL_FRAGMENT_SHADER); if ( *fragShader == 0 ) return false; glAttachObjectARB(*prog, *fragShader); glLinkProgramARB(*prog); glGetObjectParameterivARB(*prog, GL_LINK_STATUS, &success); if(success!=GL_TRUE) { /* something went wrong */ int infologLength = 0; int charsWritten = 0; char *infoLog; glGetObjectParameterivARB(*prog, GL_INFO_LOG_LENGTH,&infologLength); if (infologLength > 0) { infoLog = (char *)malloc(infologLength); glGetInfoLogARB(*prog, infologLength, &charsWritten, infoLog); printf("OPENGL ERROR: Program link Error"); printf("%s\n",infoLog); free(infoLog); } return false; } return true; } bool TCOD_opengl_init_shaders(void) { int i; TCOD_color_t *fCol; if ( TCOD_ctx.renderer == TCOD_RENDERER_GLSL ) { if (! loadProgram(TCOD_con_vertex_shader, TCOD_con_pixel_shader, &conVertShader, &conFragShader, &conProgram ) ) return false; } /* Host side data init */ for(i = 0; i< ConsoleDataEnumSize; i++) { data[i] = (unsigned char *)calloc(conwidth*conheight,ConsoleDataAlignment[i]); dirty[i]=true; } /* Initialize ForeCol to 255, 255, 255, 255 */ fCol = (TCOD_color_t *)data[ForeCol]; for( i = 0; i < conwidth*conheight; i++) { fCol[i].r=255; fCol[i].g=255; fCol[i].b=255; } /* Generate Textures */ glGenTextures(3, Tex); /* Character Texture */ CHECKGL(glBindTexture(GL_TEXTURE_2D, Tex[Character])); CHECKGL(glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST )); CHECKGL(glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST )); CHECKGL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, POTconwidth, POTconheight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0)); /* ForeCol Texture */ CHECKGL(glBindTexture(GL_TEXTURE_2D, Tex[ForeCol])); CHECKGL(glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST )); CHECKGL(glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST )); CHECKGL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, POTconwidth, POTconheight, 0, GL_RGB, GL_UNSIGNED_BYTE, 0)); /* BackCol Texture */ CHECKGL(glBindTexture(GL_TEXTURE_2D, Tex[BackCol])); CHECKGL(glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST )); CHECKGL(glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST )); CHECKGL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, POTconwidth, POTconheight, 0, GL_RGB, GL_UNSIGNED_BYTE, 0)); CHECKGL(glBindTexture(GL_TEXTURE_2D, 0)); return true; } static bool updateTex(ConsoleDataEnum dataType) { GLenum Type=0; DBGCHECKGL(glBindTexture(GL_TEXTURE_2D, Tex[dataType])); switch(ConsoleDataAlignment[dataType]) { case 1: Type = GL_RED; break; /*case 2: Type = GL_RG; break; */ case 3: Type = GL_RGB; break; case 4: Type = GL_RGBA; break; } /*glPixelStorei(GL_UNPACK_ALIGNMENT, 1); */ DBGCHECKGL(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, conwidth, conheight, Type, GL_UNSIGNED_BYTE, data[dataType])); DBGCHECKGL(glBindTexture(GL_TEXTURE_2D,0)); return true; } static void updateChar(ConsoleDataEnum dataType, int BufferPos, unsigned char *c, int length, int offset) { int i; dirty[dataType] = true; /* Set dirty so Texture gets updated next frame */ for(i = 0; ich_array; int *oc; nfg = TCOD_image_get_colors(console->fg_colors); nbg = TCOD_image_get_colors(console->bg_colors); if (track_changes) { oc = cache->ch_array; ofg = TCOD_image_get_colors(cache->fg_colors); obg = TCOD_image_get_colors(cache->bg_colors); } /* update opengl data */ /* TODO use function pointers so that libtcod's putchar directly updates opengl data */ for (y=0;yr != obg->r || nbg->g != obg->g || nbg->b != obg->b || nfg->r != ofg->r || nfg->g != ofg->g || nfg->b != ofg->b || *c != *oc) { changed=true; } } if ( changed ) { TCOD_opengl_putchar_ex(x, y, TCOD_ctx.ascii_to_tcod[*c], *nfg, *nbg); } c++; nfg++; nbg++; if (track_changes) { oc++; ofg++; obg++; } } } /* check if any of the textures have changed since they were last uploaded */ for( i = 0; i< ConsoleDataEnumSize; i++) { if(dirty[i]) { updateTex((ConsoleDataEnum)i); dirty[i] = false; } } if ( TCOD_ctx.renderer == TCOD_RENDERER_OPENGL ) { /* fixed pipeline for video cards without pixel shader support */ /* draw the background as a single quad */ float texw=(float)conwidth/POTconwidth; float texh=(float)conheight/POTconheight; float fonw=(float)fontwidth/(TCOD_ctx.fontNbCharHoriz*POTfontwidth); float fonh=(float)fontheight/(TCOD_ctx.fontNbCharVertic*POTfontheight); DBGCHECKGL(glBindTexture(GL_TEXTURE_2D, Tex[BackCol])); DBGCHECKGL(glBegin(GL_QUADS); glColor3f(1.0,1.0,1.0); glTexCoord2f( 0.0, 0.0 ); glVertex2i( 0, 0); glTexCoord2f( 0.0, texh); glVertex2i( 0, conheight ); glTexCoord2f( texw, texh ); glVertex2i( conwidth, conheight); glTexCoord2f( texw, 0.0 ); glVertex2i( conwidth, 0 ); glEnd()); /* draw the characters (one quad per cell) */ DBGCHECKGL(glBindTexture(GL_TEXTURE_2D, font_tex)); c = console->ch_array; nfg = TCOD_image_get_colors(console->fg_colors); nbg = TCOD_image_get_colors(console->bg_colors); for (y=0;yValidate()); */ DBGCHECKGL(glBegin(GL_QUADS); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,-1.0f,0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f,-1.0f,0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f,1.0f, 0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,1.0f,0.0f); glEnd()); DBGCHECKGL(glBindTexture(GL_TEXTURE_2D, 0)); DBGCHECKGL(glUseProgramObjectARB(0)); } /* fading overlay */ if ( fade != 255 ) { int x=0,y=0; if ( TCOD_ctx.fullscreen ) { x=TCOD_ctx.fullscreen_offsetx/TCOD_ctx.font_width; y=TCOD_ctx.fullscreen_offsety/TCOD_ctx.font_height; } glBegin( GL_QUADS ); glColor4f(TCOD_ctx.fading_color.r/255.0f,TCOD_ctx.fading_color.g/255.0f,TCOD_ctx.fading_color.b/255.0f,1.0f-fade/255.0f); glVertex2i( x, y); glVertex2i( x, y+conheight ); glVertex2i( x+conwidth, y+conheight ); glVertex2i( x+conwidth, y); glEnd(); } return true; } void TCOD_opengl_swap(void) { SDL_GL_SwapWindow(window); } void * TCOD_opengl_get_screen(void) { SDL_Surface *surf; int pixw,pixh,offx=0,offy=0,x,y; uint32_t mask,nmask; /* allocate a pixel buffer */ pixw=TCOD_ctx.root->w * TCOD_ctx.font_width; pixh=TCOD_ctx.root->h * TCOD_ctx.font_height; surf=TCOD_sys_get_surface(pixw,pixh,false); if ( TCOD_ctx.fullscreen ) { offx=TCOD_ctx.fullscreen_offsetx; offy=TCOD_ctx.fullscreen_offsety; } /* get pixel data from opengl */ glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT ); glPixelStorei(GL_PACK_ROW_LENGTH, 0); glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(offx,offy,pixw,pixh, GL_RGB, GL_UNSIGNED_BYTE, surf->pixels); glPopClientAttrib(); /* vertical flip (opengl has lower-left origin, SDL upper left) */ mask=surf->format->Rmask|surf->format->Gmask|surf->format->Bmask; nmask=~mask; for (x=0; x < surf->w; x++) { for (y=0; y < surf->h/2; y++) { int offsrc=x*3+y*surf->pitch; int offdst=x*3+(surf->h-1-y)*surf->pitch; uint32_t *pixsrc = (uint32_t *)(((uint8_t*)surf->pixels)+offsrc); uint32_t *pixdst = (uint32_t *)(((uint8_t*)surf->pixels)+offdst); uint32_t tmp = *pixsrc; *pixsrc = ((*pixsrc) & nmask) | ((*pixdst) & mask); *pixdst = ((*pixdst) & nmask) | (tmp & mask); } } return (void *)surf; } #endif /* NO_OPENGL */ #endif /* TCOD_SDL2 */ libtcod-1.6.4+dfsg/src/sys_sdl2_c.c000066400000000000000000000457001321276576200171010ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef TCOD_SDL2 #include #include #include #include #include #include static SDL_Surface* scale_screen=NULL; static bool clear_screen=false; static TCOD_console_data_t *root_console_cache; /* cache for previous values */ /* This just forces a complete redraw, bypassing the usual rendering of changes. */ void TCOD_sys_set_clear_screen(void) { clear_screen=true; } static void get_closest_mode(int *w, int *h) { SDL_DisplayMode wantedmode, closestmode; wantedmode.w = *w; wantedmode.h = *h; wantedmode.format = 0; /* don't care for rest. */ wantedmode.refresh_rate = 0; wantedmode.driverdata = 0; if (SDL_GetClosestDisplayMode(window?SDL_GetWindowDisplayIndex(window):0, &wantedmode, &closestmode) == &closestmode) { *w=closestmode.w; *h=closestmode.h; } } /* * Separate out the actual rendering, so that render to texture can be done. */ static void actual_rendering(void) { SDL_Rect srcRect, dstRect; SDL_Texture *texture; if (scale_data.min_scale_factor - 1e-3f > scale_factor) { /* Prepare for the unscaled and centered copy of the entire console. */ srcRect.x=0; srcRect.y=0; srcRect.w=scale_screen->w; srcRect.h=scale_screen->h; if (TCOD_ctx.fullscreen) { dstRect.x=TCOD_ctx.fullscreen_offsetx; dstRect.y=TCOD_ctx.fullscreen_offsety; } else { dstRect.x=0; dstRect.y=0; } dstRect.w=scale_screen->w; dstRect.h=scale_screen->h; } else { /* Prepare for the scaled copy of the displayed console area. */ srcRect.x=scale_data.src_x0; srcRect.y=scale_data.src_y0; srcRect.w=scale_data.src_copy_width; srcRect.h=scale_data.src_copy_height; dstRect.x=scale_data.dst_offset_x; dstRect.y=scale_data.dst_offset_y; dstRect.w=scale_data.dst_display_width; dstRect.h=scale_data.dst_display_height; } if ( TCOD_ctx.sdl_cbk ) { TCOD_ctx.sdl_cbk((void *)scale_screen); } texture = SDL_CreateTextureFromSurface(renderer, scale_screen); SDL_RenderCopy(renderer, texture, &srcRect, &dstRect); SDL_DestroyTexture(texture); } /* Return an up-to-date cache for the root console, create or resize the cache if needed */ static TCOD_console_data_t *ensure_cache(TCOD_console_data_t* root) { if (!root_console_cache || root_console_cache->w != root->w || root_console_cache->h != root->h) { if (root_console_cache) { TCOD_console_delete(root_console_cache); } root_console_cache = TCOD_console_new(root->w, root->h); } return root_console_cache; } /* In order to avoid rendering race conditions and the ensuing segmentation * faults, this should only be called when it would normally be and not * specifically to force screen refreshes. To this end, and to avoid * threading complications it takes care of special cases internally. */ static void render(TCOD_SDL_driver_t *sdl, void *vbitmap, TCOD_console_data_t *console) { if ( TCOD_ctx.renderer == TCOD_RENDERER_SDL ) { int console_width_p = console->w * TCOD_ctx.font_width; int console_height_p = console->h * TCOD_ctx.font_height; /* Make a bitmap of exact rendering size and correct format. */ if (scale_screen == NULL) { int bpp; uint32_t rmask, gmask, bmask, amask; if (SDL_PixelFormatEnumToMasks(SDL_GetWindowPixelFormat(window), &bpp, &rmask, &gmask, &bmask, &amask) == SDL_FALSE) { TCOD_fatal("SDL : failed to create scaling surface : indeterminate window pixel format"); return; } scale_screen=SDL_CreateRGBSurface(SDL_SWSURFACE,console_width_p,console_height_p,bpp,rmask,gmask,bmask,amask); if (scale_screen == NULL) { TCOD_fatal("SDL : failed to create scaling surface"); return; } } else if (clear_screen) { clear_screen=false; SDL_FillRect(scale_screen,0,0); /* Implicitly do complete console redraw, not just tracked changes. */ TCOD_console_set_dirty(0, 0, console->w, console->h); } TCOD_sys_console_to_bitmap(scale_screen, console, ensure_cache(console)); /* Scale the rendered bitmap to the screen, preserving aspect ratio, and blit it. * This data is also used for console coordinate resolution.. */ if (scale_data.last_scale_factor != scale_factor || scale_data.last_scale_xc != sdl->scale_xc || scale_data.last_scale_yc != sdl->scale_yc || scale_data.last_fullscreen != TCOD_ctx.fullscreen || scale_data.force_recalc) { /* Preserve old value of input variables, to enable recalculation if they change. */ scale_data.last_scale_factor = scale_factor; scale_data.last_scale_xc = sdl->scale_xc; scale_data.last_scale_yc = sdl->scale_yc; scale_data.last_fullscreen = TCOD_ctx.fullscreen; scale_data.force_recalc = 0; if (scale_data.last_fullscreen) { scale_data.surface_width = TCOD_ctx.actual_fullscreen_width; scale_data.surface_height = TCOD_ctx.actual_fullscreen_height; } else { scale_data.surface_width = console_width_p; scale_data.surface_height = console_height_p; } scale_data.min_scale_factor = MAX((float)console_width_p/scale_data.surface_width, (float)console_height_p/scale_data.surface_height); if (scale_data.min_scale_factor > 1.0f) scale_data.min_scale_factor = 1.0f; /*printf("min_scale_factor %0.3f = MAX(%d/%d, %d/%d)", scale_data.min_scale_factor, console_width_p, scale_data.surface_width, console_height_p, scale_data.surface_height);*/ scale_data.dst_height_width_ratio = (float)scale_data.surface_height/scale_data.surface_width; scale_data.src_proportionate_width = (int)(console_width_p / scale_factor); scale_data.src_proportionate_height = (int)((console_width_p * scale_data.dst_height_width_ratio) / scale_factor); /* Work out how much of the console to copy. */ scale_data.src_x0 = (int)((sdl->scale_xc * console_width_p) - (0.5f * scale_data.src_proportionate_width)); if (scale_data.src_x0 + scale_data.src_proportionate_width > console_width_p) scale_data.src_x0 = console_width_p - scale_data.src_proportionate_width; if (scale_data.src_x0 < 0) scale_data.src_x0 = 0; scale_data.src_copy_width = scale_data.src_proportionate_width; if (scale_data.src_x0 + scale_data.src_copy_width > console_width_p) scale_data.src_copy_width = console_width_p - scale_data.src_x0; scale_data.src_y0 = (int)((sdl->scale_yc * console_height_p) - (0.5f * scale_data.src_proportionate_height)); if (scale_data.src_y0 + scale_data.src_proportionate_height > console_height_p) scale_data.src_y0 = console_height_p - scale_data.src_proportionate_height; if (scale_data.src_y0 < 0) scale_data.src_y0 = 0; scale_data.src_copy_height = scale_data.src_proportionate_height; if (scale_data.src_y0 + scale_data.src_copy_height > console_height_p) scale_data.src_copy_height = console_height_p - scale_data.src_y0; scale_data.dst_display_width = (scale_data.src_copy_width * scale_data.surface_width) / scale_data.src_proportionate_width; scale_data.dst_display_height = (scale_data.src_copy_height * scale_data.surface_height) / scale_data.src_proportionate_height; scale_data.dst_offset_x = (scale_data.surface_width - scale_data.dst_display_width)/2; scale_data.dst_offset_y = (scale_data.surface_height - scale_data.dst_display_height)/2; } SDL_RenderClear(renderer); actual_rendering(); SDL_RenderPresent(renderer); } #ifndef NO_OPENGL else { TCOD_opengl_render(oldFade, NULL, console, ensure_cache(console)); TCOD_opengl_swap(); } #endif oldFade=(int)TCOD_console_get_fade(); } /* Return the current root console cache if it exists, or NULL. */ static TCOD_console_data_t *get_root_console_cache(void){ return root_console_cache; } static SDL_Surface *create_surface(int width, int height, bool with_alpha) { uint32_t rmask,gmask,bmask,amask; SDL_Surface *bitmap; int flags=SDL_SWSURFACE; if ( with_alpha ) { if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) { rmask=0x000000FF; gmask=0x0000FF00; bmask=0x00FF0000; amask=0xFF000000; } else { rmask=0xFF000000; gmask=0x00FF0000; bmask=0x0000FF00; amask=0x000000FF; } } else { if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) { rmask=0x0000FF; gmask=0x00FF00; bmask=0xFF0000; } else { rmask=0xFF0000; gmask=0x00FF00; bmask=0x0000FF; } amask=0; } bitmap=SDL_CreateRGBSurface(flags,width,height, with_alpha ? 32:24, rmask,gmask,bmask,amask); if ( with_alpha ) { SDL_SetSurfaceAlphaMod(bitmap, 255); } return (void *)bitmap; } static void create_window(int w, int h, bool fullscreen) { uint32_t winflags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL; #if defined(TCOD_ANDROID) /* Android should always be fullscreen. */ TCOD_ctx.fullscreen = fullscreen = true; #endif if ( fullscreen ) { find_resolution(); #ifndef NO_OPENGL if (TCOD_ctx.renderer != TCOD_RENDERER_SDL ) { TCOD_opengl_init_attributes(); winflags |= SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS | SDL_WINDOW_OPENGL; # if defined(TCOD_ANDROID) && defined(FUTURE_SUPPORT) winflags |= SDL_WINDOW_RESIZABLE; # endif window = SDL_CreateWindow(TCOD_ctx.window_title,SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,TCOD_ctx.actual_fullscreen_width,TCOD_ctx.actual_fullscreen_height,winflags); if ( window && TCOD_opengl_init_state(w, h, charmap) && TCOD_opengl_init_shaders() ) { TCOD_LOG(("Using %s renderer...\n",TCOD_ctx.renderer == TCOD_RENDERER_GLSL ? "GLSL" : "OPENGL")); } else { TCOD_LOG(("Fallback to SDL renderer...\n")); TCOD_ctx.renderer = TCOD_RENDERER_SDL; } } #endif if (TCOD_ctx.renderer == TCOD_RENDERER_SDL ) { winflags |= SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS; # if defined(TCOD_ANDROID) && defined(FUTURE_SUPPORT) winflags |= SDL_WINDOW_RESIZABLE; # endif window = SDL_CreateWindow(TCOD_ctx.window_title,SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, TCOD_ctx.actual_fullscreen_width,TCOD_ctx.actual_fullscreen_height,winflags); if ( window == NULL ) TCOD_fatal_nopar("SDL : cannot set fullscreen video mode"); } SDL_ShowCursor(0); SDL_GetWindowSize(window,&TCOD_ctx.actual_fullscreen_width,&TCOD_ctx.actual_fullscreen_height); TCOD_sys_init_screen_offset(); } else { #ifndef NO_OPENGL if (TCOD_ctx.renderer != TCOD_RENDERER_SDL ) { TCOD_opengl_init_attributes(); winflags |= SDL_WINDOW_OPENGL; window = SDL_CreateWindow(TCOD_ctx.window_title,SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,w*TCOD_ctx.font_width,h*TCOD_ctx.font_height,winflags); if ( window && TCOD_opengl_init_state(w, h, charmap) && TCOD_opengl_init_shaders() ) { TCOD_LOG(("Using %s renderer...\n",TCOD_ctx.renderer == TCOD_RENDERER_GLSL ? "GLSL" : "OPENGL")); } else { TCOD_LOG(("Fallback to SDL renderer...\n")); TCOD_ctx.renderer = TCOD_RENDERER_SDL; } } #endif if (TCOD_ctx.renderer == TCOD_RENDERER_SDL ) { window = SDL_CreateWindow(TCOD_ctx.window_title,SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,w*TCOD_ctx.font_width,h*TCOD_ctx.font_height,winflags); TCOD_LOG(("Using SDL renderer...\n")); } if ( window == NULL ) TCOD_fatal_nopar("SDL : cannot create window"); } if (TCOD_ctx.renderer == TCOD_RENDERER_SDL ) { renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); if ( renderer == NULL ) TCOD_fatal_nopar("SDL : cannot create renderer"); SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); } } static void destroy_window(void) { #ifndef NO_OPENGL if (TCOD_ctx.renderer == TCOD_RENDERER_OPENGL || TCOD_ctx.renderer == TCOD_RENDERER_GLSL) { TCOD_opengl_uninit_state(); } #endif if (scale_screen) { SDL_FreeSurface(scale_screen); scale_screen = NULL; } if (renderer) { SDL_DestroyRenderer(renderer); renderer = NULL; } if (window) { SDL_DestroyWindow(window); window = NULL; } } static void set_fullscreen(bool fullscreen) { bool mouseOn=SDL_ShowCursor(-1); if ( fullscreen ) { find_resolution(); SDL_SetWindowFullscreen(window, fullscreen); SDL_ShowCursor(mouseOn ? 1:0); SDL_GetWindowSize(window,&TCOD_ctx.actual_fullscreen_width,&TCOD_ctx.actual_fullscreen_height); TCOD_sys_init_screen_offset(); } else { SDL_SetWindowFullscreen(window, fullscreen); SDL_ShowCursor(mouseOn ? 1:0); TCOD_ctx.fullscreen_offsetx=0; TCOD_ctx.fullscreen_offsety=0; } TCOD_ctx.fullscreen=fullscreen; oldFade=-1; /* to redraw the whole screen */ } static void set_window_title(const char *title) { SDL_SetWindowTitle(window, title); } static void save_screenshot(const char *filename) { if ( TCOD_ctx.renderer == TCOD_RENDERER_SDL ) { /* This would be a lot easier if image saving could do textures. */ SDL_Rect rect; uint32_t format; SDL_Texture *texture; SDL_RenderGetViewport(renderer, &rect); format = SDL_GetWindowPixelFormat(window); texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_TARGET, rect.w, rect.h); if (0 != texture) { if (SDL_SetRenderTarget(renderer, texture)) { void *pixels; int pitch, access; actual_rendering(); SDL_SetRenderTarget(renderer, NULL); rect.x = rect.y = rect.w = rect.h = 0; if (-1 != SDL_QueryTexture(texture, &format, &access, &rect.w, &rect.h) && -1 != SDL_LockTexture(texture, NULL, &pixels, &pitch)) { int depth; uint32_t rmask, gmask, bmask, amask; if (SDL_TRUE == SDL_PixelFormatEnumToMasks(format, &depth, &rmask, &gmask, &bmask, &amask)) { SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(pixels, rect.w, rect.h, depth, pitch, rmask, gmask, bmask, amask); TCOD_sys_save_bitmap((void *)surface,filename); SDL_FreeSurface(surface); } else TCOD_LOG(("TCOD_sys_save_screenshot - failed call to SDL_PixelFormatEnumToMasks")); SDL_UnlockTexture(texture); } else TCOD_LOG(("TCOD_sys_save_screenshot - failed call to SDL_QueryTexture or SDL_LockTexture")); } else TCOD_LOG(("TCOD_sys_save_screenshot - failed call to SDL_SetRenderTarget")); SDL_DestroyTexture(texture); } else TCOD_LOG(("TCOD_sys_save_screenshot - failed call to SDL_CreateTexture")); #ifndef NO_OPENGL } else { SDL_Surface *screenshot=(SDL_Surface *)TCOD_opengl_get_screen(); TCOD_sys_save_bitmap((void *)screenshot,filename); SDL_FreeSurface(screenshot); #endif } } /* get desktop resolution */ static void get_current_resolution(int *w, int *h) { int displayidx; SDL_Rect rect = { 0, 0, 0, 0 }; if (window) { TCOD_IFNOT(window) return; displayidx = SDL_GetWindowDisplayIndex(window); TCOD_IFNOT(displayidx >= 0) return; } else { /* No window if no console, but user can want to know res before opening one. */ TCOD_IFNOT(SDL_GetNumVideoDisplays() > 0) return; displayidx = 0; } TCOD_IFNOT(SDL_GetDisplayBounds(displayidx, &rect) == 0) return; *w=rect.w; *h=rect.h; } static void set_mouse_position(int x, int y) { SDL_WarpMouseInWindow(window, (uint16_t)x,(uint16_t)y); } static char *get_clipboard_text(void) { #ifdef TCOD_LINUX /* X11 clipboard is inaccessible without an open window. https://bugzilla.libsdl.org/show_bug.cgi?id=3222 */ if (!window) return ""; #endif /* We hold onto the last clipboard text pointer SDL gave us. For C API callers it can be considered a borrowed reference. For Python ctypes API callers, the contents are copied into the Python string that is constructed from it. */ if (last_clipboard_text) { SDL_free(last_clipboard_text); last_clipboard_text = NULL; } last_clipboard_text = SDL_GetClipboardText(); return last_clipboard_text; } static bool set_clipboard_text(const char *text) { #ifdef TCOD_LINUX /* X11 clipboard is inaccessible without an open window. https://bugzilla.libsdl.org/show_bug.cgi?id=3222 */ if (!window) return false; #endif return SDL_SetClipboardText(text) == 0; } /* android compatible file access functions */ static bool file_read(const char *filename, unsigned char **buf, size_t *size) { int64_t filesize; /* get file size */ SDL_RWops *rwops= SDL_RWFromFile(filename,"rb"); if (!rwops) return false; SDL_RWseek(rwops,0,RW_SEEK_END); filesize=SDL_RWtell(rwops); SDL_RWseek(rwops,0,RW_SEEK_SET); /* allocate buffer */ *buf = (unsigned char *)malloc(sizeof(unsigned char)*filesize); /* read from file */ if (SDL_RWread(rwops,*buf,sizeof(unsigned char),filesize) != filesize) { SDL_RWclose(rwops); free(*buf); return false; } SDL_RWclose(rwops); *size=filesize; return true; } static bool file_exists(const char * filename) { SDL_RWops *rwops; rwops = SDL_RWFromFile(filename,"rb"); if (rwops) { SDL_RWclose(rwops); return true; } return false; } static bool file_write(const char *filename, unsigned char *buf, uint32_t size) { SDL_RWops *rwops= SDL_RWFromFile(filename,"wb"); if (!rwops) return false; SDL_RWwrite(rwops,buf,sizeof(unsigned char),size); SDL_RWclose(rwops); return true; } static void shutdown(void) { if (last_clipboard_text) { SDL_free(last_clipboard_text); last_clipboard_text = NULL; } if (root_console_cache) { TCOD_console_delete(root_console_cache); root_console_cache = NULL; } } TCOD_SDL_driver_t *SDL_implementation_factory(void) { TCOD_SDL_driver_t *ret=(TCOD_SDL_driver_t *)calloc(1,sizeof(TCOD_SDL_driver_t)); ret->scale_xc = 0.5f; ret->scale_yc = 0.5f; ret->get_closest_mode = get_closest_mode; ret->render = render; ret->create_surface = create_surface; ret->create_window = create_window; ret->destroy_window = destroy_window; ret->set_fullscreen = set_fullscreen; ret->set_window_title = set_window_title; ret->save_screenshot = save_screenshot; ret->get_current_resolution = get_current_resolution; ret->set_mouse_position = set_mouse_position; ret->get_clipboard_text = get_clipboard_text; ret->set_clipboard_text = set_clipboard_text; ret->file_read = file_read; ret->file_exists = file_exists; ret->file_write = file_write; ret->shutdown = shutdown; ret->get_root_console_cache = get_root_console_cache; return ret; } #endif /* TCOD_SDL2 */ libtcod-1.6.4+dfsg/src/sys_sdl_c.c000066400000000000000000001676231321276576200170300ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef TCOD_SDL2 #include #include #include #include #include #include #include #include #include static TCOD_SDL_driver_t *sdl=NULL; /* library initialization function */ #ifdef TCOD_WINDOWS #include BOOL APIENTRY DllMain( HINSTANCE hModule, DWORD reason, LPVOID reserved) { switch (reason ) { case DLL_PROCESS_ATTACH : sdl = SDL_implementation_factory(); break; default : break; } return TRUE; } #else void __attribute__ ((constructor)) DllMain(void) { sdl = SDL_implementation_factory(); } #endif #if defined(__ANDROID__) #define TCOD_TOUCH_INPUT #define MAX_TOUCH_FINGERS 5 typedef struct { int nupdates; /* how many updates have happened since the first finger was pressed. */ uint32_t ticks0; /* current number of ticks at start of touch event sequence. */ SDL_FingerID finger_id; /* the last finger which was pressed. */ int coords[MAX_TOUCH_FINGERS][2]; /* absolute position of each finger. */ int coords_delta[MAX_TOUCH_FINGERS][2]; /* absolute position of each finger. */ int consolecoords[MAX_TOUCH_FINGERS][2]; /* cell coordinates in the root console for each finger. */ int consolecoords_delta[MAX_TOUCH_FINGERS][2]; /* cell coordinates in the root console for each finger. */ int nfingers; /* number of unique fingers employed at any time during this. */ int nfingerspressed; /* number of those fingers currently still pressed. */ SDL_FingerID finger_ids[MAX_TOUCH_FINGERS]; char fingerspressed[MAX_TOUCH_FINGERS]; } TCOD_touch_t; #endif /* to enable bitmap locking. Is there any use ?? makes the OSX port renderer to fail */ /*#define USE_SDL_LOCKS */ /* image support stuff */ bool TCOD_sys_check_bmp(const char *filename); SDL_Surface *TCOD_sys_read_bmp(const char *filename); void TCOD_sys_write_bmp(const SDL_Surface *surf, const char *filename); bool TCOD_sys_check_png(const char *filename); SDL_Surface *TCOD_sys_read_png(const char *filename); void TCOD_sys_write_png(const SDL_Surface *surf, const char *filename); typedef struct { char *extension; bool (*check_type)(const char *filename); SDL_Surface *(*read)(const char *filename); void (*write)(const SDL_Surface *surf, const char *filename); } image_support_t; static image_support_t image_type[] = { { "BMP", TCOD_sys_check_bmp, TCOD_sys_read_bmp, TCOD_sys_write_bmp }, { "PNG", TCOD_sys_check_png, TCOD_sys_read_png, TCOD_sys_write_png }, { NULL, NULL, NULL, NULL }, }; scale_data_t scale_data={0}; SDL_Window* window=NULL; SDL_Renderer* renderer=NULL; float scale_factor=1.0f; SDL_Surface* charmap=NULL; char *last_clipboard_text = NULL; static bool has_startup=false; #define MAX_SCALE_FACTOR 5.0f /* font transparent color */ static TCOD_color_t fontKeyCol={0,0,0}; static uint32_t sdl_key=0, rgb_mask=0, nrgb_mask=0; /* mouse stuff */ static bool mousebl=false; static bool mousebm=false; static bool mousebr=false; static bool mouse_force_bl=false; static bool mouse_force_bm=false; static bool mouse_force_br=false; #ifdef TCOD_TOUCH_INPUT static bool mouse_touch=true; #endif /* minimum length for a frame (when fps are limited) */ static int min_frame_length=0; static int min_frame_length_backup=0; /* number of frames in the last second */ static int fps=0; /* current number of frames */ static int cur_fps=0; /* length of the last rendering loop */ static float last_frame_length=0.0f; static TCOD_color_t *charcols=NULL; static bool *first_draw=NULL; static bool key_status[TCODK_CHAR+1]; int oldFade=-1; /* convert SDL vk to a char (depends on the keyboard layout) */ typedef struct { SDL_Keycode sdl_key; int tcod_key; } vk_to_c_entry; #define NUM_VK_TO_C_ENTRIES 10 static vk_to_c_entry vk_to_c[NUM_VK_TO_C_ENTRIES]; /* convert ASCII code to TCOD layout position */ static int init_ascii_to_tcod[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 77, 0, 0, 0, 0, 0, /* ASCII 0 to 15 */ 71, 70, 72, 0, 0, 0, 0, 0, 64, 65, 67, 66, 0, 73, 68, 69, /* ASCII 16 to 31 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* ASCII 32 to 47 */ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* ASCII 48 to 63 */ 32, 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110, /* ASCII 64 to 79 */ 111,112,113,114,115,116,117,118,119,120,121, 33, 34, 35, 36, 37, /* ASCII 80 to 95 */ 38,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142, /* ASCII 96 to 111 */ 143,144,145,146,147,148,149,150,151,152,153, 39, 40, 41, 42, 0, /* ASCII 112 to 127 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ASCII 128 to 143 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ASCII 144 to 159 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ASCII 160 to 175 */ 43, 44, 45, 46, 49, 0, 0, 0, 0, 81, 78, 87, 88, 0, 0, 55, /* ASCII 176 to 191 */ 53, 50, 52, 51, 47, 48, 0, 0, 85, 86, 82, 84, 83, 79, 80, 0, /* ASCII 192 to 207 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 54, 0, 0, 0, 0, 0, /* ASCII 208 to 223 */ 74, 75, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 0, 0, 0, 0, /* ASCII 224 to 239 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ASCII 240 to 255 */ }; static void alloc_ascii_tables(void) { if ( TCOD_ctx.ascii_to_tcod ) free(TCOD_ctx.ascii_to_tcod); if ( charcols ) { free(charcols); free(first_draw); } TCOD_ctx.ascii_to_tcod = (int *)calloc(sizeof(int),TCOD_ctx.max_font_chars); charcols = (TCOD_color_t *)calloc(sizeof(TCOD_color_t),TCOD_ctx.max_font_chars); first_draw =(bool *)calloc(sizeof(bool),TCOD_ctx.max_font_chars); memcpy(TCOD_ctx.ascii_to_tcod,init_ascii_to_tcod,sizeof(int)*256); } static void check_ascii_to_tcod(void) { if ( TCOD_ctx.fontNbCharHoriz * TCOD_ctx.fontNbCharVertic != TCOD_ctx.max_font_chars ) { TCOD_ctx.max_font_chars=TCOD_ctx.fontNbCharHoriz * TCOD_ctx.fontNbCharVertic; alloc_ascii_tables(); } } void TCOD_sys_register_SDL_renderer(SDL_renderer_t renderer) { TCOD_ctx.sdl_cbk=renderer; } void TCOD_sys_map_ascii_to_font(int asciiCode, int fontCharX, int fontCharY) { if ( asciiCode > 0 && asciiCode < TCOD_ctx.max_font_chars ) TCOD_ctx.ascii_to_tcod[asciiCode] = fontCharX + fontCharY * TCOD_ctx.fontNbCharHoriz; } void TCOD_sys_load_font(void) { int i; bool hasTransparent=false; int x,y; if ( charmap ) SDL_FreeSurface(charmap); charmap=TCOD_sys_load_image(TCOD_ctx.font_file); if (charmap == NULL ) TCOD_fatal("SDL : cannot load %s",TCOD_ctx.font_file); if ( (float)(charmap->w / TCOD_ctx.fontNbCharHoriz) != charmap->w / TCOD_ctx.fontNbCharHoriz || (float)(charmap->h / TCOD_ctx.fontNbCharVertic) != charmap->h / TCOD_ctx.fontNbCharVertic ) TCOD_fatal(" %s size is not a multiple of font layout (%dx%d)\n", TCOD_ctx.font_file,TCOD_ctx.fontNbCharHoriz,TCOD_ctx.fontNbCharVertic); TCOD_ctx.font_width=charmap->w/TCOD_ctx.fontNbCharHoriz; TCOD_ctx.font_height=charmap->h/TCOD_ctx.fontNbCharVertic; /* allocated bool array for colored flags */ if ( TCOD_ctx.colored ) free(TCOD_ctx.colored); TCOD_ctx.colored=(bool *)calloc(sizeof(bool), TCOD_ctx.fontNbCharHoriz*TCOD_ctx.fontNbCharVertic); check_ascii_to_tcod(); /* figure out what kind of font we have */ /* check if the alpha layer is actually used */ if ( charmap->format->BytesPerPixel == 4 ) { printf ("32bits font... checking for alpha layer... "); for (x=0; !hasTransparent && x < charmap->w; x ++ ) { for (y=0;!hasTransparent && y < charmap->h; y++ ) { uint8_t*pixel=(uint8_t*)(charmap->pixels) + y * charmap->pitch + x * charmap->format->BytesPerPixel; uint8_t alpha=*((pixel)+charmap->format->Ashift/8); if ( alpha < 255 ) { hasTransparent=true; } } } printf (hasTransparent ? "present\n" : "not present\n"); } else if ( charmap->format->BytesPerPixel != 3 ) { /* convert to 24 bits */ SDL_Surface *temp; printf ("font bpp < 24. converting to 24bits\n"); temp=(SDL_Surface *)TCOD_sys_get_surface(charmap->w,charmap->h,false); SDL_BlitSurface(charmap,NULL,temp,NULL); SDL_FreeSurface(charmap); charmap=temp; } else { printf ("24 bits font.\n"); } if (! hasTransparent ) { /* alpha layer not used */ int keyx,keyy; uint8_t*pixel; /* the key color is found on the character corresponding to space ' ' */ if ( TCOD_ctx.font_tcod_layout ) { keyx = TCOD_ctx.font_width/2; keyy = TCOD_ctx.font_height/2; } else if (TCOD_ctx.font_in_row) { keyx = ((int)(' ') % TCOD_ctx.fontNbCharHoriz ) * TCOD_ctx.font_width + TCOD_ctx.font_width/2; keyy = ((int)(' ') / TCOD_ctx.fontNbCharHoriz ) * TCOD_ctx.font_height + TCOD_ctx.font_height/2; } else { keyx = ((int)(' ') / TCOD_ctx.fontNbCharVertic ) * TCOD_ctx.font_width + TCOD_ctx.font_width/2; keyy = ((int)(' ') % TCOD_ctx.fontNbCharVertic ) * TCOD_ctx.font_height + TCOD_ctx.font_height/2; } pixel=(uint8_t*)(charmap->pixels) + keyy * charmap->pitch + keyx * charmap->format->BytesPerPixel; fontKeyCol.r=*((pixel)+charmap->format->Rshift/8); fontKeyCol.g=*((pixel)+charmap->format->Gshift/8); fontKeyCol.b=*((pixel)+charmap->format->Bshift/8); printf ("key color : %d %d %d\n",fontKeyCol.r,fontKeyCol.g,fontKeyCol.b); if ( ! TCOD_ctx.font_greyscale && charmap->format->BytesPerPixel == 4 ) { /* 32 bits font but alpha layer not used. convert to 24 bits (faster) */ SDL_Surface *temp; printf ("32bits font with no alpha => converting to faster 24 bits\n"); temp=(SDL_Surface *)TCOD_sys_get_surface(charmap->w,charmap->h,false); SDL_BlitSurface(charmap,NULL,temp,NULL); SDL_FreeSurface(charmap); charmap=temp; } } /* detect colored tiles */ for (i=0; i < TCOD_ctx.fontNbCharHoriz*TCOD_ctx.fontNbCharVertic; i++ ) { int px,py,cx,cy; bool end=false; cx=(i%TCOD_ctx.fontNbCharHoriz); cy=(i/TCOD_ctx.fontNbCharHoriz); for( px=0; !end && px < TCOD_ctx.font_width; px++ ) { for (py=0; !end && py < TCOD_ctx.font_height; py++ ) { uint8_t*pixel=(uint8_t*)(charmap->pixels) + (cy*TCOD_ctx.font_height+py) * charmap->pitch + (cx*TCOD_ctx.font_width+px) * charmap->format->BytesPerPixel; uint8_t r=*((pixel)+charmap->format->Rshift/8); uint8_t g=*((pixel)+charmap->format->Gshift/8); uint8_t b=*((pixel)+charmap->format->Bshift/8); if ( charmap->format->BytesPerPixel == 3 ) { /* ignore key color */ if ( r == fontKeyCol.r && g == fontKeyCol.g && b == fontKeyCol.b ) continue; } /* colored tile if a pixel is not desaturated */ if ( r != g || g !=b || b != r ) { TCOD_ctx.colored[i]=true; printf ("character for ascii code %d is colored\n",i); end=true; } } } } /* convert 24/32 bits greyscale to 32bits font with alpha layer */ if ( ! hasTransparent && TCOD_ctx.font_greyscale ) { bool invert=( fontKeyCol.r > 128 ); /* black on white font ? */ /* convert the surface to 32 bits if needed */ if ( charmap->format->BytesPerPixel != 4 ) { SDL_Surface *temp; printf("24bits greyscale font. converting to 32bits\n"); temp=(SDL_Surface *)TCOD_sys_get_surface(charmap->w,charmap->h,true); SDL_BlitSurface(charmap,NULL,temp,NULL); SDL_FreeSurface(charmap); charmap=temp; } for (i=0; i < TCOD_ctx.fontNbCharHoriz*TCOD_ctx.fontNbCharVertic; i++ ) { int cx,cy; cx=(i%TCOD_ctx.fontNbCharHoriz); cy=(i/TCOD_ctx.fontNbCharHoriz); /* fill the surface with white (except colored tiles), use alpha layer for characters */ for (x=cx*TCOD_ctx.font_width; x < (cx+1)*TCOD_ctx.font_width; x ++ ) { for (y=cy*TCOD_ctx.font_height;y < (cy+1)*TCOD_ctx.font_height; y++ ) { if ( ! TCOD_ctx.colored[i]) { uint8_t*pixel=(uint8_t*)(charmap->pixels) + y * charmap->pitch + x * charmap->format->BytesPerPixel; uint8_t r=*((pixel)+charmap->format->Rshift/8); *((pixel)+charmap->format->Ashift/8) = (invert ? 255-r : r); *((pixel)+charmap->format->Rshift/8)=255; *((pixel)+charmap->format->Gshift/8)=255; *((pixel)+charmap->format->Bshift/8)=255; } else { uint8_t*pixel=(uint8_t*)(charmap->pixels) + y * charmap->pitch + x * charmap->format->BytesPerPixel; uint8_t r=*((pixel)+charmap->format->Rshift/8); uint8_t g=*((pixel)+charmap->format->Gshift/8); uint8_t b=*((pixel)+charmap->format->Bshift/8); if ( r == fontKeyCol.r && g == fontKeyCol.g && b == fontKeyCol.b ) { *((pixel)+charmap->format->Ashift/8) = 0; } else { *((pixel)+charmap->format->Ashift/8) = 255; } } } } } } sdl_key=SDL_MapRGB(charmap->format,fontKeyCol.r,fontKeyCol.g,fontKeyCol.b); rgb_mask=charmap->format->Rmask|charmap->format->Gmask|charmap->format->Bmask; nrgb_mask = ~ rgb_mask; sdl_key &= rgb_mask; /* remove the alpha part */ if ( charmap->format->BytesPerPixel == 3 ) SDL_SetColorKey(charmap,SDL_TRUE|SDL_RLEACCEL,sdl_key); for (i=0; i < TCOD_ctx.fontNbCharHoriz*TCOD_ctx.fontNbCharVertic; i++ ) { charcols[i]=fontKeyCol; first_draw[i]=true; } check_ascii_to_tcod(); if (!TCOD_ctx.font_tcod_layout) { /* apply standard ascii mapping */ if ( TCOD_ctx.font_in_row ) { /* for font in row */ for (i=0; i < TCOD_ctx.max_font_chars; i++ ) TCOD_ctx.ascii_to_tcod[i]=i; } else { /* for font in column */ for (i=0; i < TCOD_ctx.max_font_chars; i++ ) { int fy = i % TCOD_ctx.fontNbCharVertic; int fx = i / TCOD_ctx.fontNbCharVertic; TCOD_ctx.ascii_to_tcod[i]=fx + fy * TCOD_ctx.fontNbCharHoriz; } } } } void TCOD_sys_set_custom_font(const char *fontFile,int nb_ch, int nb_cv, int flags) { strcpy(TCOD_ctx.font_file,fontFile); /* if layout not defined, assume ASCII_INCOL */ if (flags == 0 || flags == TCOD_FONT_TYPE_GREYSCALE) flags |= TCOD_FONT_LAYOUT_ASCII_INCOL; TCOD_ctx.font_in_row=((flags & TCOD_FONT_LAYOUT_ASCII_INROW) != 0); TCOD_ctx.font_greyscale = ((flags & TCOD_FONT_TYPE_GREYSCALE) != 0 ); TCOD_ctx.font_tcod_layout = ((flags & TCOD_FONT_LAYOUT_TCOD) != 0 ); if ( nb_ch> 0 ) { TCOD_ctx.fontNbCharHoriz=nb_ch; TCOD_ctx.fontNbCharVertic=nb_cv; } else { if ( ( flags & TCOD_FONT_LAYOUT_ASCII_INROW ) || ( flags & TCOD_FONT_LAYOUT_ASCII_INCOL ) ) { TCOD_ctx.fontNbCharHoriz=16; TCOD_ctx.fontNbCharVertic=16; } else { TCOD_ctx.fontNbCharHoriz=32; TCOD_ctx.fontNbCharVertic=8; } } if ( TCOD_ctx.font_tcod_layout ) TCOD_ctx.font_in_row=true; check_ascii_to_tcod(); /* screw up things on linux64. apparently, useless TCOD_sys_load_font(); */ } void find_resolution(void) { TCOD_ctx.actual_fullscreen_width=TCOD_ctx.fullscreen_width>TCOD_ctx.root->w*TCOD_ctx.font_width?TCOD_ctx.fullscreen_width:TCOD_ctx.root->w*TCOD_ctx.font_width; TCOD_ctx.actual_fullscreen_height=TCOD_ctx.fullscreen_height>TCOD_ctx.root->h*TCOD_ctx.font_height?TCOD_ctx.fullscreen_height:TCOD_ctx.root->h*TCOD_ctx.font_height; sdl->get_closest_mode(&TCOD_ctx.actual_fullscreen_width,&TCOD_ctx.actual_fullscreen_height); } void *TCOD_sys_create_bitmap_for_console(TCOD_console_t console) { int w,h; w = TCOD_console_get_width(console) * TCOD_ctx.font_width; h = TCOD_console_get_height(console) * TCOD_ctx.font_height; return TCOD_sys_get_surface(w,h,false); } static void TCOD_sys_render(void *vbitmap, TCOD_console_data_t* console) { sdl->render(sdl, vbitmap, console); } void TCOD_sys_console_to_bitmap(void *vbitmap, TCOD_console_data_t* console, TCOD_console_data_t* cache) { static SDL_Surface *charmap_backup=NULL; SDL_Surface *bitmap = (SDL_Surface *)vbitmap; int x,y; uint32_t sdl_back=0, sdl_fore=0; TCOD_color_t fading_color = TCOD_console_get_fading_color(); int fade = (int)TCOD_console_get_fade(); /* can only track changes on the root console */ bool track_changes = (cache && oldFade == fade); uint8_t bpp = charmap->format->BytesPerPixel; int *c = console->ch_array; int *oc; TCOD_color_t *ofg, *obg, *nfg, *nbg; int hdelta; if ( bpp == 4 ) { hdelta=(charmap->pitch - TCOD_ctx.font_width*bpp)/4; } else { hdelta=(charmap->pitch - TCOD_ctx.font_width*bpp); } nfg = TCOD_image_get_colors(console->fg_colors); nbg = TCOD_image_get_colors(console->bg_colors); if (track_changes) { oc = cache->ch_array; ofg = TCOD_image_get_colors(cache->fg_colors); obg = TCOD_image_get_colors(cache->bg_colors); } if ( charmap_backup == NULL ) { charmap_backup=(SDL_Surface *)TCOD_sys_get_surface(charmap->w,charmap->h,true); SDL_BlitSurface(charmap,NULL,charmap_backup,NULL); } #ifdef USE_SDL_LOCKS if ( SDL_MUSTLOCK( bitmap ) && SDL_LockSurface( bitmap ) < 0 ) return; #endif for (y = 0; y < console->h; y++) { for (x = 0; x < console->w; x++) { SDL_Rect srcRect,dstRect; bool changed=true; if ( track_changes ) { changed=false; if ( nbg->r != obg->r || nbg->g != obg->g || nbg->b != obg->b || nfg->r != ofg->r || nfg->g != ofg->g || nfg->b != ofg->b || *c != *oc) { changed=true; } } if ( changed ) { TCOD_color_t b=*nbg; dstRect.x=x*TCOD_ctx.font_width; dstRect.y=y*TCOD_ctx.font_height; dstRect.w=TCOD_ctx.font_width; dstRect.h=TCOD_ctx.font_height; /* draw background */ if ( fade != 255 ) { b.r = ((int)b.r) * fade / 255 + ((int)fading_color.r) * (255-fade)/255; b.g = ((int)b.g) * fade / 255 + ((int)fading_color.g) * (255-fade)/255; b.b = ((int)b.b) * fade / 255 + ((int)fading_color.b) * (255-fade)/255; } sdl_back=SDL_MapRGB(bitmap->format,b.r,b.g,b.b); SDL_FillRect(bitmap,&dstRect,sdl_back); if ( *c != ' ' ) { /* draw foreground */ int ascii = TCOD_ctx.ascii_to_tcod[*c]; TCOD_color_t *curtext = &charcols[ascii]; bool first = first_draw[ascii]; TCOD_color_t f=*nfg; if ( fade != 255 ) { f.r = ((int)f.r) * fade / 255 + ((int)fading_color.r) * (255-fade)/255; f.g = ((int)f.g) * fade / 255 + ((int)fading_color.g) * (255-fade)/255; f.b = ((int)f.b) * fade / 255 + ((int)fading_color.b) * (255-fade)/255; } /* only draw character if foreground color != background color */ if ( f.r != b.r || f.g != b.g || f.b != b.b ) { if ( charmap->format->Amask == 0 && f.r == fontKeyCol.r && f.g == fontKeyCol.g && f.b == fontKeyCol.b ) { /* cannot draw with the key color... */ if ( f.r < 255 ) f.r++; else f.r--; } srcRect.x = (ascii%TCOD_ctx.fontNbCharHoriz)*TCOD_ctx.font_width; srcRect.y = (ascii/TCOD_ctx.fontNbCharHoriz)*TCOD_ctx.font_height; srcRect.w=TCOD_ctx.font_width; srcRect.h=TCOD_ctx.font_height; if ( charmap && (first || curtext->r != f.r || curtext->g != f.g || curtext->b!=f.b) ) { /* change the character color in the font */ first_draw[ascii]=false; sdl_fore=SDL_MapRGB(charmap->format,f.r,f.g,f.b) & rgb_mask; *curtext=f; #ifdef USE_SDL_LOCKS if ( SDL_MUSTLOCK(charmap) ) { if ( SDL_LockSurface(charmap) < 0 ) return; } #endif if ( bpp == 4 ) { /* 32 bits font : fill the whole character with foreground color */ uint32_t *pix = (uint32_t *)(((uint8_t*)charmap->pixels)+srcRect.x*bpp + srcRect.y*charmap->pitch); int h=TCOD_ctx.font_height; if ( ! TCOD_ctx.colored[ascii] ) { while ( h-- ) { int w=TCOD_ctx.font_width; while ( w-- ) { (*pix) &= nrgb_mask; (*pix) |= sdl_fore; pix++; } pix += hdelta; } } else { /* colored character : multiply color with foreground color */ uint32_t *pixorig = (uint32_t *)(((uint8_t*)charmap_backup->pixels)+srcRect.x*bpp + srcRect.y*charmap_backup->pitch); int hdelta_backup=(charmap_backup->pitch - TCOD_ctx.font_width*4)/4; while (h> 0) { int w=TCOD_ctx.font_width; while ( w > 0 ) { int r=(int)(*((uint8_t*)(pixorig)+charmap_backup->format->Rshift/8)); int g=(int)(*((uint8_t*)(pixorig)+charmap_backup->format->Gshift/8)); int b=(int)(*((uint8_t*)(pixorig)+charmap_backup->format->Bshift/8)); (*pix) &= nrgb_mask; /* erase the color */ r = r * f.r / 255; g = g * f.g / 255; b = b * f.b / 255; /* set the new color */ (*pix) |= (r<format->Rshift)|(g<format->Gshift)|(b<format->Bshift); w--; pix++; pixorig++; } h--; pix += hdelta; pixorig += hdelta_backup; } } } else { /* 24 bits font : fill only non key color pixels */ uint32_t *pix = (uint32_t *)(((uint8_t*)charmap->pixels)+srcRect.x*bpp + srcRect.y*charmap->pitch); int h=TCOD_ctx.font_height; if ( ! TCOD_ctx.colored[ascii] ) { while ( h-- ) { int w=TCOD_ctx.font_width; while ( w-- ) { if (((*pix) & rgb_mask) != sdl_key ) { (*pix) &= nrgb_mask; (*pix) |= sdl_fore; } pix = (uint32_t *) (((uint8_t*)pix)+3); } pix = (uint32_t *) (((uint8_t*)pix)+hdelta); } } else { /* colored character : multiply color with foreground color */ uint32_t *pixorig = (uint32_t *)(((uint8_t*)charmap_backup->pixels)+srcRect.x*4 + srcRect.y*charmap_backup->pitch); /* charmap_backup is always 32 bits */ int hdelta_backup=(charmap_backup->pitch - TCOD_ctx.font_width*4)/4; while (h> 0) { int w=TCOD_ctx.font_width; while ( w > 0 ) { if (((*pixorig) & rgb_mask) != sdl_key ) { int r=(int)(*((uint8_t*)(pixorig)+charmap_backup->format->Rshift/8)); int g=(int)(*((uint8_t*)(pixorig)+charmap_backup->format->Gshift/8)); int b=(int)(*((uint8_t*)(pixorig)+charmap_backup->format->Bshift/8)); (*pix) &= nrgb_mask; /* erase the color */ r = r * f.r / 255; g = g * f.g / 255; b = b * f.b / 255; /* set the new color */ (*pix) |= (r<format->Rshift)|(g<format->Gshift)|(b<format->Bshift); } w--; pix = (uint32_t *) (((uint8_t*)pix)+3); pixorig ++; } h--; pix = (uint32_t *) (((uint8_t*)pix)+hdelta); pixorig += hdelta_backup; } } } #ifdef USE_SDL_LOCKS if ( SDL_MUSTLOCK(charmap) ) { SDL_UnlockSurface(charmap); } #endif } SDL_BlitSurface(charmap,&srcRect,bitmap,&dstRect); } } } c++; nfg++; nbg++; if (track_changes) { oc++; ofg++; obg++; } } } #ifdef USE_SDL_LOCKS if ( SDL_MUSTLOCK( bitmap ) ) SDL_UnlockSurface( bitmap ); #endif if (cache) { /* update previous values cache */ memcpy(cache->ch_array, console->ch_array, sizeof(console->ch_array[0]) * console->w * console->h); TCOD_image_mipmap_copy_internal(console->fg_colors, cache->fg_colors); TCOD_image_mipmap_copy_internal(console->bg_colors, cache->bg_colors); } } void *TCOD_sys_get_surface(int width, int height, bool alpha) { return sdl->create_surface(width,height,alpha); } void TCOD_sys_update_char(int asciiCode, int fontx, int fonty, TCOD_image_t img, int x, int y) { int px,py; int iw,ih; static TCOD_color_t pink={255,0,255}; TCOD_sys_map_ascii_to_font(asciiCode,fontx,fonty); TCOD_image_get_size(img,&iw,&ih); for (px=0; px < TCOD_ctx.font_width; px ++ ) { for (py=0;py < TCOD_ctx.font_height; py++ ) { TCOD_color_t col=TCOD_white; uint8_t*pixel; uint8_t bpp; if ( (unsigned)(x+px) < (unsigned)iw && (unsigned)(y+py) < (unsigned)ih ) { col=TCOD_image_get_pixel(img,x+px,y+py); } pixel=(uint8_t*)(charmap->pixels) + (fonty*TCOD_ctx.font_height+py) * charmap->pitch + (fontx*TCOD_ctx.font_width+px) * charmap->format->BytesPerPixel; bpp = charmap->format->BytesPerPixel; if (bpp == 4 ) { *((pixel)+charmap->format->Ashift/8) = col.r; *((pixel)+charmap->format->Rshift/8)=255; *((pixel)+charmap->format->Gshift/8)=255; *((pixel)+charmap->format->Bshift/8)=255; } else { *((pixel)+charmap->format->Rshift/8)=col.r; *((pixel)+charmap->format->Gshift/8)=col.g; *((pixel)+charmap->format->Bshift/8)=col.b; } } } charcols[asciiCode]=pink; TCOD_sys_set_dirty_character_code(asciiCode); } void TCOD_sys_startup(void) { if (has_startup) return; #ifndef NDEBUG SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE); #endif TCOD_IFNOT(SDL_Init(SDL_INIT_VIDEO) >= 0 ) return; memset(&TCOD_ctx.key_state,0,sizeof(TCOD_key_t)); TCOD_ctx.max_font_chars=256; alloc_ascii_tables(); #ifndef NO_OPENGL TCOD_opengl_init_attributes(); #endif has_startup=true; } void TCOD_sys_shutdown(void) { if (!has_startup) return; TCOD_sys_uninit(); sdl->shutdown(); SDL_Quit(); memset(&scale_data, 0, sizeof(scale_data_t)); has_startup = false; } static void TCOD_sys_load_player_config(void) { const char *renderer; const char *font; int fullscreenWidth,fullscreenHeight; /* define file structure */ TCOD_parser_t parser=TCOD_parser_new(); TCOD_parser_struct_t libtcod = TCOD_parser_new_struct(parser, "libtcod"); TCOD_struct_add_property(libtcod, "renderer", TCOD_TYPE_STRING, false); TCOD_struct_add_property(libtcod, "font", TCOD_TYPE_STRING, false); TCOD_struct_add_property(libtcod, "fontInRow", TCOD_TYPE_BOOL, false); TCOD_struct_add_property(libtcod, "fontGreyscale", TCOD_TYPE_BOOL, false); TCOD_struct_add_property(libtcod, "fontTcodLayout", TCOD_TYPE_BOOL, false); TCOD_struct_add_property(libtcod, "fontNbCharHoriz", TCOD_TYPE_INT, false); TCOD_struct_add_property(libtcod, "fontNbCharVertic", TCOD_TYPE_INT, false); TCOD_struct_add_property(libtcod, "fullscreen", TCOD_TYPE_BOOL, false); TCOD_struct_add_property(libtcod, "fullscreenWidth", TCOD_TYPE_INT, false); TCOD_struct_add_property(libtcod, "fullscreenHeight", TCOD_TYPE_INT, false); TCOD_struct_add_property(libtcod, "fullscreenScaling", TCOD_TYPE_BOOL, false); /* parse file */ TCOD_parser_run(parser,"./libtcod.cfg",NULL); /* set user preferences */ renderer=TCOD_parser_get_string_property(parser, "libtcod.renderer"); if ( renderer != NULL ) { /* custom renderer */ if ( TCOD_strcasecmp(renderer,"GLSL") == 0 ) TCOD_ctx.renderer=TCOD_RENDERER_GLSL; else if ( TCOD_strcasecmp(renderer,"OPENGL") == 0 ) TCOD_ctx.renderer=TCOD_RENDERER_OPENGL; else if ( TCOD_strcasecmp(renderer,"SDL") == 0 ) TCOD_ctx.renderer=TCOD_RENDERER_SDL; else printf ("Warning : unknown renderer '%s' in libtcod.cfg\n", renderer); } font=TCOD_parser_get_string_property(parser, "libtcod.font"); if ( font != NULL ) { /* custom font */ if ( TCOD_sys_file_exists(font)) { int fontNbCharHoriz,fontNbCharVertic; strcpy(TCOD_ctx.font_file,font); TCOD_ctx.font_in_row=TCOD_parser_get_bool_property(parser,"libtcod.fontInRow"); TCOD_ctx.font_greyscale=TCOD_parser_get_bool_property(parser,"libtcod.fontGreyscale"); TCOD_ctx.font_tcod_layout=TCOD_parser_get_bool_property(parser,"libtcod.fontTcodLayout"); fontNbCharHoriz=TCOD_parser_get_int_property(parser,"libtcod.fontNbCharHoriz"); fontNbCharVertic=TCOD_parser_get_int_property(parser,"libtcod.fontNbCharVertic"); if ( fontNbCharHoriz > 0 ) TCOD_ctx.fontNbCharHoriz=fontNbCharHoriz; if ( fontNbCharVertic > 0 ) TCOD_ctx.fontNbCharVertic=fontNbCharVertic; if ( charmap ) { SDL_FreeSurface(charmap); charmap=NULL; } } else { printf ("Warning : font file '%s' does not exist\n",font); } } /* custom fullscreen resolution */ TCOD_ctx.fullscreen=TCOD_parser_get_bool_property(parser,"libtcod.fullscreen"); fullscreenWidth=TCOD_parser_get_int_property(parser,"libtcod.fullscreenWidth"); fullscreenHeight=TCOD_parser_get_int_property(parser,"libtcod.fullscreenHeight"); if ( fullscreenWidth > 0 ) TCOD_ctx.fullscreen_width=fullscreenWidth; if ( fullscreenHeight > 0 ) TCOD_ctx.fullscreen_height=fullscreenHeight; } TCOD_renderer_t TCOD_sys_get_renderer(void) { return TCOD_ctx.renderer; } void TCOD_sys_set_renderer(TCOD_renderer_t renderer) { if ( renderer == TCOD_ctx.renderer ) return; TCOD_ctx.renderer=renderer; TCOD_sys_uninit(); TCOD_sys_init(TCOD_ctx.root, TCOD_ctx.fullscreen); TCOD_console_set_window_title(TCOD_ctx.window_title); TCOD_console_set_dirty(0,0,TCOD_ctx.root->w,TCOD_ctx.root->h); } void TCOD_sys_init_screen_offset(void) { TCOD_ctx.fullscreen_offsetx=(TCOD_ctx.actual_fullscreen_width-TCOD_ctx.root->w*TCOD_ctx.font_width)/2; TCOD_ctx.fullscreen_offsety=(TCOD_ctx.actual_fullscreen_height-TCOD_ctx.root->h*TCOD_ctx.font_height)/2; } bool TCOD_sys_init(TCOD_console_data_t *console, bool fullscreen) { static TCOD_renderer_t last_renderer=TCOD_RENDERER_SDL; static char last_font[512]=""; TCOD_sys_startup(); /* check if there is a user (player) config file */ if ( TCOD_sys_file_exists("./libtcod.cfg")) { /* yes, read it */ TCOD_sys_load_player_config(); if (TCOD_ctx.fullscreen) fullscreen=true; } if (last_renderer != TCOD_ctx.renderer || ! charmap || strcmp(last_font,TCOD_ctx.font_file) != 0) { /* reload the font when switching renderer to restore original character colors */ TCOD_sys_load_font(); } sdl->create_window(console->w, console->h, fullscreen); memset(key_status,0,sizeof(bool)*(TCODK_CHAR+1)); return true; } void TCOD_sys_uninit(void) { if (!has_startup) return; sdl->destroy_window(); } void TCOD_sys_save_bitmap(void *bitmap, const char *filename) { image_support_t *img=image_type; while ( img->extension != NULL && strcasestr(filename,img->extension) == NULL ) img++; if ( img->extension == NULL || img->write == NULL ) img=image_type; /* default to bmp */ img->write((SDL_Surface *)bitmap,filename); } void TCOD_sys_save_screenshot(const char *filename) { char buf[128]; if ( filename == NULL ) { /* generate filename */ int idx=0; do { FILE *f=NULL; sprintf(buf,"./screenshot%03d.png",idx); f=fopen(buf,"rb"); if ( ! f ) filename=buf; else { idx++; fclose(f); } } while(!filename); } sdl->save_screenshot(filename); } void TCOD_sys_set_fullscreen(bool fullscreen) { TCOD_ctx.fullscreen=fullscreen; sdl->set_fullscreen(fullscreen); } void TCOD_sys_set_scale_factor(float value) { float old_scale_factor = scale_factor; scale_factor = value; if (scale_factor + 1e-3 < scale_data.min_scale_factor) scale_factor = scale_data.min_scale_factor; else if (scale_factor - 1e-3 > MAX_SCALE_FACTOR) scale_factor = MAX_SCALE_FACTOR; /*printf("scale_factor: %0.3f -> %0.3f (wanted: %0.3f)", old_scale_factor, scale_factor, value);*/ } void TCOD_sys_set_window_title(const char *title) { strcpy(TCOD_ctx.window_title,title); sdl->set_window_title(title); } void TCOD_sys_flush(bool render) { static uint32_t old_time,new_time=0, elapsed=0; int32_t frame_time,time_to_wait; if ( render ) { TCOD_sys_render(NULL, TCOD_ctx.root); } old_time=new_time; new_time=TCOD_sys_elapsed_milli(); /* If TCOD has been terminated and restarted. */ if (old_time > new_time) old_time = elapsed = 0; if ( new_time / 1000 != elapsed ) { /* update fps every second */ fps=cur_fps; cur_fps=0; elapsed=new_time/1000; } /* if too fast, wait */ frame_time=(new_time - old_time); last_frame_length = frame_time * 0.001f; cur_fps++; time_to_wait=min_frame_length-frame_time; if (old_time > 0 && time_to_wait > 0) { TCOD_sys_sleep_milli(time_to_wait); new_time = TCOD_sys_elapsed_milli(); frame_time=(new_time - old_time); } last_frame_length = frame_time * 0.001f; } static char TCOD_sys_get_vk(SDL_Keycode sdl_key) { int i; for (i = 0; i < NUM_VK_TO_C_ENTRIES; i++) { if (vk_to_c[i].sdl_key == sdl_key) { vk_to_c[i].sdl_key = 0; return vk_to_c[i].tcod_key; } } return 0; } static void TCOD_sys_set_vk(SDL_Keycode sdl_key, char tcod_key) { int i; for (i = 0; i < NUM_VK_TO_C_ENTRIES; i++) { if (vk_to_c[i].sdl_key == 0) { vk_to_c[i].sdl_key = sdl_key; vk_to_c[i].tcod_key = tcod_key; break; } } } static void TCOD_sys_convert_event(SDL_Event *ev, TCOD_key_t *ret) { SDL_KeyboardEvent *kev=&ev->key; /* SDL2 does not map keycodes and modifiers to characters, this is on the developer. Presumably in order to avoid problems with different keyboard layouts, they are expected to write their own key mapping editing code for the user. */ if (SDLK_SCANCODE_MASK == (kev->keysym.sym & SDLK_SCANCODE_MASK)) ret->c = 0; else ret->c = kev->keysym.sym; if ( ( kev->keysym.mod & (KMOD_LCTRL|KMOD_RCTRL) ) != 0 ) { /* when pressing CTRL-A, we don't get unicode for 'a', but unicode for CTRL-A = 1. Fix it */ if ( kev->keysym.sym >= SDLK_a && kev->keysym.sym <= SDLK_z ) { ret->c = 'a'+(kev->keysym.sym - SDLK_a); } } if ( ev->type == SDL_KEYDOWN ) TCOD_sys_set_vk(kev->keysym.sym, ret->c); else if (ev->type == SDL_KEYUP ) ret->c = TCOD_sys_get_vk(kev->keysym.sym); switch(kev->keysym.sym) { case SDLK_ESCAPE : ret->vk=TCODK_ESCAPE;break; case SDLK_SPACE : ret->vk=TCODK_SPACE; break; case SDLK_BACKSPACE : ret->vk=TCODK_BACKSPACE;break; case SDLK_TAB : ret->vk=TCODK_TAB;break; case SDLK_RETURN : ret->vk=TCODK_ENTER;break; case SDLK_PAUSE : ret->vk=TCODK_PAUSE;break; case SDLK_PAGEUP : ret->vk=TCODK_PAGEUP;break; case SDLK_PAGEDOWN : ret->vk=TCODK_PAGEDOWN;break; case SDLK_HOME : ret->vk=TCODK_HOME;break; case SDLK_END : ret->vk=TCODK_END;break; case SDLK_DELETE : ret->vk=TCODK_DELETE;break; case SDLK_INSERT : ret->vk=TCODK_INSERT; break; case SDLK_LALT : case SDLK_RALT : ret->vk=TCODK_ALT;break; case SDLK_LCTRL : case SDLK_RCTRL : ret->vk=TCODK_CONTROL;break; case SDLK_LSHIFT : case SDLK_RSHIFT : ret->vk=TCODK_SHIFT;break; case SDLK_PRINTSCREEN : ret->vk=TCODK_PRINTSCREEN;break; case SDLK_LEFT : ret->vk=TCODK_LEFT;break; case SDLK_UP : ret->vk=TCODK_UP;break; case SDLK_RIGHT : ret->vk=TCODK_RIGHT;break; case SDLK_DOWN : ret->vk=TCODK_DOWN;break; case SDLK_F1 : ret->vk=TCODK_F1;break; case SDLK_F2 : ret->vk=TCODK_F2;break; case SDLK_F3 : ret->vk=TCODK_F3;break; case SDLK_F4 : ret->vk=TCODK_F4;break; case SDLK_F5 : ret->vk=TCODK_F5;break; case SDLK_F6 : ret->vk=TCODK_F6;break; case SDLK_F7 : ret->vk=TCODK_F7;break; case SDLK_F8 : ret->vk=TCODK_F8;break; case SDLK_F9 : ret->vk=TCODK_F9;break; case SDLK_F10 : ret->vk=TCODK_F10;break; case SDLK_F11 : ret->vk=TCODK_F11;break; case SDLK_F12 : ret->vk=TCODK_F12;break; case SDLK_0 : ret->vk=TCODK_0;break; case SDLK_1 : ret->vk=TCODK_1;break; case SDLK_2 : ret->vk=TCODK_2;break; case SDLK_3 : ret->vk=TCODK_3;break; case SDLK_4 : ret->vk=TCODK_4;break; case SDLK_5 : ret->vk=TCODK_5;break; case SDLK_6 : ret->vk=TCODK_6;break; case SDLK_7 : ret->vk=TCODK_7;break; case SDLK_8 : ret->vk=TCODK_8;break; case SDLK_9 : ret->vk=TCODK_9;break; case SDLK_RGUI : ret->vk=TCODK_RWIN;break; case SDLK_LGUI : ret->vk=TCODK_LWIN;break; case SDLK_NUMLOCKCLEAR : ret->vk=TCODK_NUMLOCK;break; case SDLK_KP_0 : ret->vk=TCODK_KP0;break; case SDLK_KP_1 : ret->vk=TCODK_KP1;break; case SDLK_KP_2 : ret->vk=TCODK_KP2;break; case SDLK_KP_3 : ret->vk=TCODK_KP3;break; case SDLK_KP_4 : ret->vk=TCODK_KP4;break; case SDLK_KP_5 : ret->vk=TCODK_KP5;break; case SDLK_KP_6 : ret->vk=TCODK_KP6;break; case SDLK_KP_7 : ret->vk=TCODK_KP7;break; case SDLK_KP_8 : ret->vk=TCODK_KP8;break; case SDLK_KP_9 : ret->vk=TCODK_KP9;break; case SDLK_KP_DIVIDE : ret->vk=TCODK_KPDIV;break; case SDLK_KP_MULTIPLY : ret->vk=TCODK_KPMUL;break; case SDLK_KP_PLUS : ret->vk=TCODK_KPADD;break; case SDLK_KP_MINUS : ret->vk=TCODK_KPSUB;break; case SDLK_KP_ENTER : ret->vk=TCODK_KPENTER;break; case SDLK_KP_PERIOD : ret->vk=TCODK_KPDEC;break; default : ret->vk=TCODK_CHAR; break; } } static TCOD_key_t TCOD_sys_SDLtoTCOD(SDL_Event *ev, int flags) { TCOD_key_t *ret = &TCOD_ctx.key_state; ret->vk=TCODK_NONE; ret->c=0; ret->pressed=0; switch (ev->type) { /* handled in TCOD_sys_handle_event */ /* case SDL_QUIT : case SDL_VIDEOEXPOSE : case SDL_MOUSEBUTTONDOWN : { case SDL_MOUSEBUTTONUP : { break; */ case SDL_KEYUP : { SDL_KeyboardEvent *kev=&ev->key; TCOD_key_t tmpkey; switch(kev->keysym.sym) { case SDLK_LALT : ret->lalt=0; break; case SDLK_RALT : ret->ralt=0; break; case SDLK_LCTRL : ret->lctrl=0; break; case SDLK_RCTRL : ret->rctrl=0; break; case SDLK_LSHIFT : ret->shift=0; break; case SDLK_RSHIFT : ret->shift=0; break; case SDLK_LGUI : ret->lmeta=0; break; case SDLK_RGUI : ret->rmeta=0; break; default:break; } TCOD_sys_convert_event(ev,&tmpkey); key_status[tmpkey.vk]=false; if ( flags & TCOD_KEY_RELEASED ) { ret->vk=tmpkey.vk; ret->c=tmpkey.c; ret->pressed=0; } } break; case SDL_KEYDOWN : { SDL_KeyboardEvent *kev=&ev->key; TCOD_key_t tmpkey; switch(kev->keysym.sym) { case SDLK_LALT : ret->lalt=1; break; case SDLK_RALT : ret->ralt=1; break; case SDLK_LCTRL : ret->lctrl=1; break; case SDLK_RCTRL : ret->rctrl=1; break; case SDLK_LSHIFT : ret->shift=1; break; case SDLK_RSHIFT : ret->shift=1; break; case SDLK_LGUI : ret->lmeta=1; break; case SDLK_RGUI : ret->rmeta=1; break; default : break; } TCOD_sys_convert_event(ev,&tmpkey); key_status[tmpkey.vk]=true; if ( flags & TCOD_KEY_PRESSED ) { ret->vk=tmpkey.vk; ret->c=tmpkey.c; ret->pressed=1; } } break; } return *ret; } bool TCOD_sys_is_key_pressed(TCOD_keycode_t key) { return key_status[key]; } #ifdef TCOD_TOUCH_INPUT static TCOD_touch_t tcod_touch={0}; static int TCOD_sys_get_touch_finger_index(SDL_FingerID fingerId) { int i; for (i = 0; i < tcod_touch.nfingers; i++) if (tcod_touch.finger_ids[i] == fingerId) return i; if (i == tcod_touch.nfingers && i+1 <= MAX_TOUCH_FINGERS) { tcod_touch.nfingers += 1; tcod_touch.finger_ids[i] = fingerId; return i; } return -1; } #endif void TCOD_sys_unproject_screen_coords(int sx, int sy, int *ssx, int *ssy) { if (scale_data.dst_display_width != 0 ) { *ssx = (scale_data.src_x0 + ((sx - scale_data.dst_offset_x) * scale_data.src_copy_width) / scale_data.dst_display_width); *ssy = (scale_data.src_y0 + ((sy - scale_data.dst_offset_y) * scale_data.src_copy_width) / scale_data.dst_display_width); } else { *ssx=sx - TCOD_ctx.fullscreen_offsetx; *ssy=sy - TCOD_ctx.fullscreen_offsety; } } void TCOD_sys_convert_console_to_screen_coords(int cx, int cy, int *sx, int *sy) { *sx = scale_data.dst_offset_x + ((cx * TCOD_ctx.font_width - scale_data.src_x0) * scale_data.dst_display_width) / scale_data.src_copy_width; *sy = scale_data.dst_offset_y + ((cy * TCOD_ctx.font_height - scale_data.src_y0) * scale_data.dst_display_height) / scale_data.src_copy_height; } void TCOD_sys_convert_screen_to_console_coords(int sx, int sy, int *cx, int *cy) { int ssx, ssy; TCOD_sys_unproject_screen_coords(sx, sy, &ssx, &ssy); *cx = ssx / TCOD_ctx.font_width; *cy = ssy / TCOD_ctx.font_height; } static TCOD_mouse_t tcod_mouse={0,0,0,0,0,0,0,0,false,false,false,false,false,false,false,false}; static TCOD_event_t TCOD_sys_handle_event(SDL_Event *ev,TCOD_event_t eventMask, TCOD_key_t *key, TCOD_mouse_t *mouse) { TCOD_event_t retMask=0; key->text[0] = '\0'; /* printf("TCOD_sys_handle_event type=%04x\n", ev->type); */ switch(ev->type) { case SDL_KEYDOWN : { TCOD_key_t tmpKey=TCOD_sys_SDLtoTCOD(ev,TCOD_KEY_PRESSED); if ( (TCOD_EVENT_KEY_PRESS & eventMask) != 0) { retMask|=TCOD_EVENT_KEY_PRESS; if ( key ) *key = tmpKey; return retMask; } } break; case SDL_KEYUP : { TCOD_key_t tmpKey=TCOD_sys_SDLtoTCOD(ev,TCOD_KEY_RELEASED); if ( (TCOD_EVENT_KEY_RELEASE & eventMask) != 0) { retMask|=TCOD_EVENT_KEY_RELEASE; if ( key ) *key = tmpKey; return retMask; } } break; case SDL_TEXTINPUT: { SDL_TextInputEvent *iev=&ev->text; *key = TCOD_ctx.key_state; key->vk = TCODK_TEXT; key->pressed = 1; strncpy(key->text, iev->text, TCOD_KEY_TEXT_SIZE); return retMask | TCOD_EVENT_KEY_PRESS; } break; #ifdef TCOD_TOUCH_INPUT /* * Need to distinguish between: * - Tap: Can be optionally delegated to a mouse press. * - Touch and drag: Should affect scaling screen position. * */ case SDL_FINGERDOWN : case SDL_FINGERUP : case SDL_FINGERMOTION : { int idx, mouse_touch_valid; float xf, yf, screen_x, screen_y; uint32_t ticks_taken = 0; /* Reset the global variable. */ if (tcod_touch.nfingerspressed == 0) { tcod_touch.nupdates = 0; tcod_touch.nfingers = 0; tcod_touch.ticks0 = SDL_GetTicks(); } else ticks_taken = SDL_GetTicks() - tcod_touch.ticks0; idx = TCOD_sys_get_touch_finger_index(ev->tfinger.fingerId); if (idx == -1) { TCOD_LOG(("ERROR: failed to allocate extra finger")); break; } /* Count the number of events contributing to an ongoing tracked touch (zeroed above in finger press). */ tcod_touch.finger_id = ev->tfinger.fingerId; tcod_touch.nupdates += 1; /* We only emulate mouse events when the first finger is the only one pressed. */ if (SDL_FINGERDOWN == ev->type) { tcod_touch.nfingerspressed += 1; tcod_touch.fingerspressed[idx] = 1; mouse_touch_valid = mouse_touch && tcod_touch.nfingerspressed == 1 && tcod_touch.fingerspressed[0]; } else if (SDL_FINGERUP == ev->type) { mouse_touch_valid = mouse_touch && tcod_touch.nfingerspressed == 1 && tcod_touch.fingerspressed[0]; tcod_touch.nfingerspressed -= 1; tcod_touch.fingerspressed[idx] = 0; } else mouse_touch_valid = mouse_touch && tcod_touch.nfingerspressed == 1 && tcod_touch.fingerspressed[0]; /* Coordinates are raw full screen positions. */ screen_x = ev->tfinger.x * scale_data.surface_width; screen_y = ev->tfinger.y * scale_data.surface_height; xf = (float)(screen_x - scale_data.dst_offset_x) / scale_data.dst_display_width; yf = (float)(screen_y - scale_data.dst_offset_y) / scale_data.dst_display_height; tcod_touch.coords[idx][0] = scale_data.src_x0 + scale_data.src_copy_width * xf; tcod_touch.coords[idx][1] = scale_data.src_y0 + scale_data.src_copy_height * yf; tcod_touch.coords_delta[idx][0] = ev->tfinger.dx * scale_data.src_proportionate_width; tcod_touch.coords_delta[idx][1] = ev->tfinger.dy * scale_data.src_proportionate_height; /* Console coordinates need to be mapped back from screen coordinates through scaling. */ tcod_touch.consolecoords[idx][0] = tcod_touch.coords[idx][0] / TCOD_ctx.font_width; tcod_touch.consolecoords[idx][1] = tcod_touch.coords[idx][1] / TCOD_ctx.font_height; tcod_touch.consolecoords_delta[idx][0] = tcod_touch.coords_delta[idx][0] / TCOD_ctx.font_width; tcod_touch.consolecoords_delta[idx][1] = tcod_touch.coords_delta[idx][1] / TCOD_ctx.font_height; if (SDL_FINGERDOWN == ev->type) { // printf("SDL_FINGERDOWN [%d] ticks=%d", tcod_touch.nupdates, ticks_taken); if ((TCOD_EVENT_FINGER_PRESS & eventMask) != 0) retMask |= TCOD_EVENT_FINGER_PRESS; if (mouse_touch_valid && (TCOD_EVENT_MOUSE_PRESS & eventMask) != 0) { mouse->lbutton=mousebl=true; retMask |= TCOD_EVENT_MOUSE_PRESS; } } else if (SDL_FINGERUP == ev->type) { // printf("SDL_FINGERUP [%d] ticks=%d", tcod_touch.nupdates, ticks_taken); if ((TCOD_EVENT_FINGER_RELEASE & eventMask) != 0) retMask |= TCOD_EVENT_FINGER_RELEASE; if (mouse_touch_valid && (TCOD_EVENT_MOUSE_RELEASE & eventMask) != 0) { if (mousebl) mouse->lbutton_pressed = mouse_force_bl=true; mouse->lbutton = mousebl=false; retMask |= TCOD_EVENT_MOUSE_RELEASE; } } else if (SDL_FINGERMOTION == ev->type) { float scale_adjust = 1.0f, xc_shift = 0.0f, yc_shift = 0.0f; // printf("SDL_FINGERMOTION [%d] ticks=%d", tcod_touch.nupdates, ticks_taken); if ((TCOD_EVENT_FINGER_MOVE & eventMask) != 0) retMask |= TCOD_EVENT_FINGER_MOVE; if (mouse_touch_valid && (TCOD_EVENT_MOUSE_MOVE & eventMask) != 0) retMask |= TCOD_EVENT_MOUSE_MOVE; if (tcod_touch.nfingerspressed == 1) { /* One finger drag AKA drag to move. * Ignore the first few move events that happen unhelpfully immediately after finger down. */ if (tcod_touch.fingerspressed[0] && (tcod_touch.coords_delta[0][0] || tcod_touch.coords_delta[0][1]) && ticks_taken > 10) { xc_shift = (float)tcod_touch.coords_delta[idx][0] / scale_data.surface_width; yc_shift = (float)tcod_touch.coords_delta[idx][1] / scale_data.surface_height; } } else if (tcod_touch.nfingerspressed == 2) { /* Two finger pinch AKA pinch to zoom * Both fingers should stay exactly where they are on the full surface * in order to manipulate the drag and zoom effect. */ if (tcod_touch.fingerspressed[0] && tcod_touch.fingerspressed[1]) { /* * New algorithm */ int f0x0 = tcod_touch.coords[0][0]-tcod_touch.coords_delta[0][0], f0y0 = tcod_touch.coords[0][1]-tcod_touch.coords_delta[0][1]; int f1x0 = tcod_touch.coords[1][0]-tcod_touch.coords_delta[1][0], f1y0 = tcod_touch.coords[1][1]-tcod_touch.coords_delta[1][1]; int f0x1 = tcod_touch.coords[0][0], f0y1 = tcod_touch.coords[0][1]; int f1x1 = tcod_touch.coords[1][0], f1y1 = tcod_touch.coords[1][1]; float p0x = (f1x0 + f0x0)/2.0f, p0y = (f1y0 + f0y0)/2.0f; float p1x = (f1x1 + f0x1)/2.0f, p1y = (f1y1 + f0y1)/2.0f; float len_previous = sqrtf((float)(pow(f0x0-f1x0,2) + pow(f0y0-f1y0,2))); float len_current = sqrt((float)(pow(f0x1-f1x1, 2) + pow(f0y1-f1y1,2))); scale_adjust = len_current/len_previous; xc_shift = ((p1x - p0x) / scale_data.surface_width); yc_shift = ((p1y - p0y) / scale_data.surface_height); } } /* Bound the translations within the console area. */ if (fabs(xc_shift) > 1e-3f) { sdl->scale_xc -= xc_shift; /* Actual display shift is the inverted finger movement. */ if (sdl->scale_xc + 1e-3f < 0.0f) sdl->scale_xc = 0.0f; if (sdl->scale_xc - 1e-3f > 1.0f) sdl->scale_xc = 1.0f; } if (fabs(yc_shift) > 1e-3f) { sdl->scale_yc -= yc_shift; /* Actual display shift is the inverted finger movement. */ if (sdl->scale_yc + 1e-3f < 0.0f) sdl->scale_yc = 0.0f; if (sdl->scale_yc - 1e-3f > 1.0f) sdl->scale_yc = 1.0f; } if (fabs(scale_adjust - 1.0f) > 1e-3f) TCOD_sys_set_scale_factor(scale_factor * scale_adjust); } /* We need to distinguish between handleable touch events, and short distinct mouse events. */ if (ticks_taken > 400 || tcod_touch.nfingers > 1) { // printf("DEF NOT MOUSE CODE[%d]", tcod_touch.nupdates); mouse->cx = 0; mouse->cy = 0; mouse->dcx = 0; mouse->dcy = 0; } else if (mouse_touch_valid && (retMask & (TCOD_EVENT_MOUSE_PRESS|TCOD_EVENT_MOUSE_RELEASE|TCOD_EVENT_MOUSE_MOVE)) != 0) { mouse->x = tcod_touch.coords[idx][0]; mouse->y = tcod_touch.coords[idx][1]; mouse->dx += tcod_touch.coords_delta[idx][0]; mouse->dy += tcod_touch.coords_delta[idx][1]; mouse->cx = tcod_touch.consolecoords[idx][0]; mouse->cy = tcod_touch.consolecoords[idx][1]; mouse->dcx = tcod_touch.consolecoords_delta[idx][0]; mouse->dcy = tcod_touch.consolecoords_delta[idx][1]; /* printf("CX,CY: %d,%d", mouse->cx,mouse->cy); */ } break; } #endif case SDL_MOUSEMOTION : if ( (TCOD_EVENT_MOUSE_MOVE & eventMask) != 0) { SDL_MouseMotionEvent *mev=&ev->motion; TCOD_sys_unproject_screen_coords(mev->x, mev->y, &mouse->x, &mouse->y); if (scale_data.surface_width != 0) { mouse->dx += (mev->xrel * scale_data.src_proportionate_width) / scale_data.surface_width; mouse->dy += (mev->yrel * scale_data.src_proportionate_height) / scale_data.surface_height; } mouse->cx = mouse->x / TCOD_ctx.font_width; mouse->cy = mouse->y / TCOD_ctx.font_height; mouse->dcx = mouse->dx / TCOD_ctx.font_width; mouse->dcy = mouse->dy / TCOD_ctx.font_height; return retMask | TCOD_EVENT_MOUSE_MOVE; } break; case SDL_MOUSEWHEEL : if (ev->wheel.y < 0) mouse->wheel_down=true; else mouse->wheel_up=true; return retMask | TCOD_EVENT_MOUSE_PRESS; break; case SDL_MOUSEBUTTONDOWN : if ( (TCOD_EVENT_MOUSE_PRESS & eventMask) != 0) { SDL_MouseButtonEvent *mev=&ev->button; retMask|=TCOD_EVENT_MOUSE_PRESS; switch (mev->button) { case SDL_BUTTON_LEFT : mouse->lbutton=mousebl=true; break; case SDL_BUTTON_MIDDLE : mouse->mbutton=mousebm=true; break; case SDL_BUTTON_RIGHT : mouse->rbutton=mousebr=true; break; } /* update mouse position */ if ( (TCOD_EVENT_MOUSE_MOVE & eventMask) == 0) { mouse->x=mev->x; mouse->y=mev->y; mouse->cx = (mouse->x - TCOD_ctx.fullscreen_offsetx) / TCOD_ctx.font_width; mouse->cy = (mouse->y - TCOD_ctx.fullscreen_offsety) / TCOD_ctx.font_height; } return retMask; } break; case SDL_MOUSEBUTTONUP : if ( (TCOD_EVENT_MOUSE_RELEASE & eventMask) != 0) { SDL_MouseButtonEvent *mev=&ev->button; retMask|=TCOD_EVENT_MOUSE_RELEASE; switch (mev->button) { case SDL_BUTTON_LEFT : if (mousebl) mouse->lbutton_pressed = mouse_force_bl=true; mouse->lbutton = mousebl=false; break; case SDL_BUTTON_MIDDLE : if (mousebm) mouse->mbutton_pressed = mouse_force_bm=true; mouse->mbutton = mousebm=false; break; case SDL_BUTTON_RIGHT : if (mousebr) mouse->rbutton_pressed = mouse_force_br=true; mouse->rbutton = mousebr=false; break; } /* update mouse position */ if ( (TCOD_EVENT_MOUSE_MOVE & eventMask) == 0) { mouse->x=mev->x; mouse->y=mev->y; mouse->cx = (mouse->x - TCOD_ctx.fullscreen_offsetx) / TCOD_ctx.font_width; mouse->cy = (mouse->y - TCOD_ctx.fullscreen_offsety) / TCOD_ctx.font_height; } return retMask; } break; case SDL_QUIT : TCOD_ctx.is_window_closed=true; break; case SDL_WINDOWEVENT : /* At this point, there are some corner cases that need dealing with. So log this. */ /* printf("SDL2 WINDOWEVENT: 0x%04x\n", ev->window.event); */ switch (ev->window.event) { #ifdef TCOD_ANDROID case SDL_WINDOWEVENT_SIZE_CHANGED: { /* printf("SDL2 WINDOWEVENT (SDL_WINDOWEVENT_SIZE_CHANGED): 0x%04x w=%d h=%d\n", ev->window.event, ev->window.data1, ev->window.data2); */ /* If the app is started while the device is locked, the screen will be in portrait mode. We need to rescale when it changes. */ if (scale_data.surface_width != ev->window.data1 || scale_data.surface_height != ev->window.data1) scale_data.force_recalc = 1; break; } #endif case SDL_WINDOWEVENT_ENTER: /**< Window has gained mouse focus */ TCOD_ctx.app_has_mouse_focus=true; break; case SDL_WINDOWEVENT_LEAVE: /**< Window has lost mouse focus */ TCOD_ctx.app_has_mouse_focus=false; break; case SDL_WINDOWEVENT_MAXIMIZED: /**< Window has been maximized */ TCOD_ctx.app_is_active=true; break; case SDL_WINDOWEVENT_MINIMIZED: /**< Window has been minimized */ TCOD_ctx.app_is_active=false; break; case SDL_WINDOWEVENT_EXPOSED: /**< Window has been returned to and needs a refresh. */ TCOD_sys_render(NULL, TCOD_ctx.root); break; #ifdef NDEBUG_HMM default: TCOD_LOG(("SDL2 WINDOWEVENT (unknown): 0x%04x\n", ev->window.event)); break; #endif } break; default : break; } return retMask; } TCOD_event_t TCOD_sys_wait_for_event(int eventMask, TCOD_key_t *key, TCOD_mouse_t *mouse, bool flush) { SDL_Event ev; TCOD_event_t retMask=0; if ( eventMask == 0 ) return 0; if ( flush ) { while ( SDL_PollEvent(&ev) ) { TCOD_sys_SDLtoTCOD(&ev,0); } } tcod_mouse.lbutton_pressed =false; tcod_mouse.rbutton_pressed =false; tcod_mouse.mbutton_pressed =false; tcod_mouse.wheel_up=false; tcod_mouse.wheel_down=false; tcod_mouse.dx=0; tcod_mouse.dy=0; if ( key ) { key->vk=TCODK_NONE; key->c=0; } do { SDL_WaitEvent(&ev); retMask=TCOD_sys_handle_event(&ev,eventMask,key,&tcod_mouse); } while ( ev.type != SDL_QUIT && (retMask & eventMask) == 0 ); if (mouse) { *mouse=tcod_mouse; } return retMask; } TCOD_event_t TCOD_sys_check_for_event(int eventMask, TCOD_key_t *key, TCOD_mouse_t *mouse) { SDL_Event ev; TCOD_event_t retMask=0; if ( eventMask == 0 ) return 0; tcod_mouse.lbutton_pressed =false; tcod_mouse.rbutton_pressed =false; tcod_mouse.mbutton_pressed =false; tcod_mouse.wheel_up=false; tcod_mouse.wheel_down=false; tcod_mouse.dx=0; tcod_mouse.dy=0; if ( key ) { key->vk=TCODK_NONE; key->c=0; } while ( SDL_PollEvent(&ev) ) { retMask=TCOD_sys_handle_event(&ev,eventMask,key,&tcod_mouse); if ((retMask & TCOD_EVENT_KEY) != 0) /* only one key event per frame */ break; } if (mouse) { *mouse=tcod_mouse; } return retMask; } TCOD_mouse_t TCOD_mouse_get_status(void) { return tcod_mouse; } /* classic keyboard functions (based on generic events) */ TCOD_key_t TCOD_sys_check_for_keypress(int flags) { static TCOD_key_t noret={TCODK_NONE,0}; TCOD_key_t key; TCOD_event_t ev = TCOD_sys_check_for_event(flags & TCOD_EVENT_KEY, &key, NULL); if ((ev & TCOD_EVENT_KEY) == 0) return noret; return key; } TCOD_key_t TCOD_sys_wait_for_keypress(bool flush) { static TCOD_key_t noret={TCODK_NONE,0}; TCOD_key_t key; TCOD_event_t ev = TCOD_sys_wait_for_event(TCOD_EVENT_KEY_PRESS, &key, NULL, flush); if ((ev & TCOD_EVENT_KEY_PRESS) == 0) return noret; return key; } void TCOD_sys_sleep_milli(uint32_t milliseconds) { SDL_Delay(milliseconds); } void *TCOD_sys_load_image(const char *filename) { image_support_t *img=image_type; while ( img->extension != NULL && !img->check_type(filename) ) img++; if ( img->extension == NULL || img->read == NULL ) return NULL; /* unknown format */ return img->read(filename); } void TCOD_sys_get_image_size(const void *image, int *w, int *h) { SDL_Surface *surf=(SDL_Surface *)image; *w = surf->w; *h = surf->h; } TCOD_color_t TCOD_sys_get_image_pixel(const void *image,int x, int y) { TCOD_color_t ret; SDL_Surface *surf=(SDL_Surface *)image; uint8_t bpp; uint8_t*bits; if ( x < 0 || y < 0 || x >= surf->w || y >= surf->h ) return TCOD_black; bpp = surf->format->BytesPerPixel; bits = ((uint8_t*)surf->pixels)+y*surf->pitch+x*bpp; switch (bpp) { case 1 : { if (surf->format->palette) { SDL_Color col = surf->format->palette->colors[(*bits)]; ret.r=col.r; ret.g=col.g; ret.b=col.b; } else return TCOD_black; } break; default : ret.r = *((bits)+surf->format->Rshift/8); ret.g = *((bits)+surf->format->Gshift/8); ret.b = *((bits)+surf->format->Bshift/8); break; } return ret; } int TCOD_sys_get_image_alpha(const void *image,int x, int y) { SDL_Surface *surf=(SDL_Surface *)image; uint8_t bpp; uint8_t*bits; if ( x < 0 || y < 0 || x >= surf->w || y >= surf->h ) return 255; bpp = surf->format->BytesPerPixel; if ( bpp != 4 ) return 255; bits = ((uint8_t*)surf->pixels)+y*surf->pitch+x*bpp; return *((bits)+surf->format->Ashift/8); } uint32_t TCOD_sys_elapsed_milli(void) { return (uint32_t)SDL_GetTicks(); } float TCOD_sys_elapsed_seconds(void) { static float div=1.0f/1000.0f; return SDL_GetTicks()*div; } void TCOD_sys_force_fullscreen_resolution(int width, int height) { TCOD_ctx.fullscreen_width=width; TCOD_ctx.fullscreen_height=height; } void * TCOD_sys_create_bitmap(int width, int height, TCOD_color_t *buf) { int x,y; SDL_PixelFormat fmt; SDL_Surface *bitmap; memset(&fmt,0,sizeof(SDL_PixelFormat)); if ( charmap != NULL ) { fmt = *charmap->format; } else { fmt.BitsPerPixel=24; fmt.Amask=0; if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) { fmt.Rmask=0x0000FF; fmt.Gmask=0x00FF00; fmt.Bmask=0xFF0000; } else { fmt.Rmask=0xFF0000; fmt.Gmask=0x00FF00; fmt.Bmask=0x0000FF; } } bitmap=SDL_CreateRGBSurface(SDL_SWSURFACE,width,height,fmt.BitsPerPixel,fmt.Rmask,fmt.Gmask,fmt.Bmask,fmt.Amask); for (x=0; x < width; x++) { for (y=0; y < height; y++) { SDL_Rect rect; uint32_t col=SDL_MapRGB(&fmt,buf[x+y*width].r,buf[x+y*width].g,buf[x+y*width].b); rect.x=x; rect.y=y; rect.w=1; rect.h=1; SDL_FillRect(bitmap,&rect,col); } } return (void *)bitmap; } void TCOD_sys_delete_bitmap(void *bitmap) { SDL_FreeSurface((SDL_Surface *)bitmap); } void TCOD_sys_set_fps(int val) { if( val == 0 ) min_frame_length=0; else min_frame_length=1000/val; } void TCOD_sys_save_fps(void) { min_frame_length_backup=min_frame_length; } void TCOD_sys_restore_fps(void) { min_frame_length=min_frame_length_backup; } int TCOD_sys_get_fps(void) { return fps; } float TCOD_sys_get_last_frame_length(void) { return last_frame_length; } void TCOD_sys_get_char_size(int *w, int *h) { *w = TCOD_ctx.font_width; *h = TCOD_ctx.font_height; } void TCOD_sys_get_current_resolution(int *w, int *h) { /* be sure that SDL is initialized */ TCOD_sys_startup(); sdl->get_current_resolution(w,h); } /* image stuff */ bool TCOD_sys_check_magic_number(const char *filename, size_t size, uint8_t*data) { uint8_t tmp[128]; size_t i; SDL_RWops *rwops = SDL_RWFromFile(filename, "rb"); if (! rwops) return false; if ( (i = rwops->read(rwops,tmp,size,1)) != 1 ) { rwops->close(rwops); return false; } rwops->close(rwops); for (i=0; i< size; i++) if (tmp[i]!=data[i]) return false; return true; } void *TCOD_sys_get_SDL_window(void) { return (void *)window; } void *TCOD_sys_get_SDL_renderer(void) { return (void *)renderer; } /* mouse stuff */ void TCOD_mouse_show_cursor(bool visible) { SDL_ShowCursor(visible ? 1 : 0); } bool TCOD_mouse_is_cursor_visible(void) { return SDL_ShowCursor(-1) ? true : false; } void TCOD_mouse_move(int x, int y) { sdl->set_mouse_position(x,y); } void TCOD_mouse_includes_touch(bool enable) { #ifdef TCOD_TOUCH_INPUT mouse_touch = enable; #endif } /*clipboard stuff */ bool TCOD_sys_clipboard_set(const char *value) { if (!has_startup) { return false; } return sdl->set_clipboard_text(value); } char *TCOD_sys_clipboard_get() { if (!has_startup) { return ""; } return sdl->get_clipboard_text(); } bool TCOD_sys_read_file(const char *filename, unsigned char **buf, size_t *size) { return sdl->file_read(filename,buf,size); } bool TCOD_sys_file_exists(const char * filename, ...) { char f[1024]; va_list ap; va_start(ap,filename); vsprintf(f,filename,ap); va_end(ap); return sdl->file_exists(f); } bool TCOD_sys_write_file(const char *filename, unsigned char *buf, uint32_t size) { return sdl->file_write(filename,buf,size); } /* Mark a rectangle of tiles dirty. */ void TCOD_sys_set_dirty(int dx, int dy, int dw, int dh) { int x, y; TCOD_console_data_t *dat = sdl->get_root_console_cache(); if (!dat) return; TCOD_IFNOT(dx < dat->w && dy < dat->h && dx + dw >= 0 && dy + dh >= 0) return; TCOD_IFNOT(dx >= 0) { dw += dx; dx = 0; } TCOD_IFNOT(dy >= 0) { dh += dy; dy = 0; } TCOD_IFNOT(dx + dw <= dat->w) dw = dat->w - dx; TCOD_IFNOT(dy + dh <= dat->h) dh = dat->h - dy; for (x = dx; x < dx + dw; ++x) { for (y = dy; y < dy + dh; ++y) { dat->ch_array[dat->w * y + x] = -1; } } } /* Mark a character dirty by invalidating all occurrences of it in the software renderer cache. Each character tile will be refreshed when the old buffer is compared to the current buffer next render. It's recommended that this method stays non-public. */ void TCOD_sys_set_dirty_character_code(int ch) { int i; TCOD_console_data_t *dat = sdl->get_root_console_cache(); if (!dat) return; for (i = 0; i < dat->w * dat->h; ++i) { if (dat->ch_array[i] == ch) { dat->ch_array[i] = -1; } } } #endif /* TCOD_SDL2 */libtcod-1.6.4+dfsg/src/sys_sdl_img_bmp.c000066400000000000000000000050261321276576200202040ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef TCOD_SDL2 #include #include #include bool TCOD_sys_check_bmp(const char *filename) { static uint8_t magic_number[]={0x42, 0x4d}; return TCOD_sys_check_magic_number(filename,sizeof(magic_number),magic_number); } SDL_Surface *TCOD_sys_read_bmp(const char *filename) { SDL_Surface *ret=SDL_LoadBMP(filename); if( !ret ) TCOD_fatal("SDL : %s",SDL_GetError()); /* convert low color images to 24 bits */ if ( ret->format->BytesPerPixel != 3 ) { uint32_t rmask,gmask,bmask; SDL_Surface * tmp; if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) { rmask=0xFF0000; gmask=0x00FF00; bmask=0x0000FF; } else { rmask=0x0000FF; gmask=0x00FF00; bmask=0xFF0000; } tmp=SDL_CreateRGBSurface(SDL_SWSURFACE,ret->w,ret->h,24, rmask, gmask, bmask, 0); SDL_BlitSurface(ret,NULL,tmp,NULL); SDL_FreeSurface(ret); ret=tmp; } return ret; } void TCOD_sys_write_bmp(const SDL_Surface *surf, const char *filename) { SDL_SaveBMP((SDL_Surface *)surf,filename); } #endif /* TCOD_SDL2 */ libtcod-1.6.4+dfsg/src/sys_sdl_img_png.c000066400000000000000000000101201321276576200202010ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef TCOD_SDL2 #include #if !defined (__HAIKU__) && !defined (__ANDROID__) #include #include #endif #include #include "png/lodepng.h" #include bool TCOD_sys_check_png(const char *filename) { static uint8_t magic_number[]={137, 80, 78, 71, 13, 10, 26, 10}; return TCOD_sys_check_magic_number(filename,sizeof(magic_number),magic_number); } SDL_Surface *TCOD_sys_read_png(const char *filename) { unsigned error; unsigned char* image; unsigned width, height, y, bpp; unsigned char* png; size_t pngsize; LodePNGState state; SDL_Surface *bitmap; unsigned char *source; unsigned int rowsize; lodepng_state_init(&state); /*optionally customize the state*/ if (!TCOD_sys_read_file(filename,&png,&pngsize)) return NULL; lodepng_inspect(&width,&height,&state, png, pngsize); bpp=lodepng_get_bpp(&state.info_png.color); if ( bpp == 24 ) { /* don't convert to 32 bits because libtcod's 24bits renderer is faster */ state.info_raw.colortype=LCT_RGB; } else if ( bpp != 24 && bpp != 32 ) { /* paletted png. convert to 24 bits */ state.info_raw.colortype=LCT_RGB; state.info_raw.bitdepth=8; bpp=24; } error = lodepng_decode(&image, &width, &height, &state, png, pngsize); free(png); if(error) { printf("error %u: %s\n", error, lodepng_error_text(error)); lodepng_state_cleanup(&state); return NULL; } /* create the SDL surface */ bitmap=TCOD_sys_get_surface(width,height,bpp==32); source=image; rowsize=width*bpp/8; for (y=0; y< height; y++ ) { uint8_t*row_pointer=(uint8_t*)(bitmap->pixels) + y * bitmap->pitch; memcpy(row_pointer,source,rowsize); source+=rowsize; } lodepng_state_cleanup(&state); free(image); return bitmap; } void TCOD_sys_write_png(const SDL_Surface *surf, const char *filename) { unsigned char *image, *dest=(unsigned char *)malloc(surf->h*surf->w*3*sizeof(char)); int x,y; unsigned char *buf; size_t size; int error; /* SDL uses 32bits format without alpha layer for screen. convert it to 24 bits */ image=dest; for (y=0; y< surf->h; y++ ) { for (x=0; x < surf->w; x++ ) { uint8_t*pixel=(uint8_t*)(surf->pixels) + y * surf->pitch + x * surf->format->BytesPerPixel; *dest++=*((pixel)+surf->format->Rshift/8); *dest++=*((pixel)+surf->format->Gshift/8); *dest++=*((pixel)+surf->format->Bshift/8); } } error=lodepng_encode_memory(&buf,&size,image,surf->w,surf->h,LCT_RGB,8); free(image); if ( ! error ) { TCOD_sys_write_file(filename,buf,(uint32_t)size); free(buf); } else { printf("error %u: %s\n", error, lodepng_error_text(error)); } } #endif /* TCOD_SDL2 */ libtcod-1.6.4+dfsg/src/tree_c.c000066400000000000000000000036041321276576200162730ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include TCOD_tree_t *TCOD_tree_new(void) { return (TCOD_tree_t *)calloc(1,sizeof(TCOD_tree_t)); } void TCOD_tree_add_son(TCOD_tree_t *node, TCOD_tree_t *son) { TCOD_tree_t *lastson = node->sons; son->father=node; while ( lastson && lastson->next ) lastson=lastson->next; if ( lastson ) { lastson->next=son; } else { node->sons=son; } } libtcod-1.6.4+dfsg/src/txtfield.cpp000066400000000000000000000052221321276576200172130ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #ifdef TCOD_CONSOLE_SUPPORT TCODText::TCODText(int x, int y, int w, int h, int max_chars){ data=TCOD_text_init(x,y,w,h,max_chars); } TCODText::TCODText(int w, int h, int max_chars){ data=TCOD_text_init2(w,h,max_chars); } TCODText::~TCODText(){ TCOD_text_delete(data); } void TCODText::setPos(int x, int y) { TCOD_text_set_pos(data,x,y); } void TCODText::setProperties(int cursor_char, int blink_interval, const char * prompt, int tab_size){ TCOD_text_set_properties(data,cursor_char,blink_interval,prompt,tab_size); } void TCODText::setColors(TCODColor fore, TCODColor back, float back_transparency){ TCOD_color_t foreground = {fore.r,fore.g,fore.b}; TCOD_color_t background = {back.r,back.g,back.b}; TCOD_text_set_colors(data,foreground,background,back_transparency); } bool TCODText::update(TCOD_key_t key){ return TCOD_text_update(data,key) != 0; } void TCODText::render(TCODConsole * con){ TCOD_text_render(data,con->data); } const char *TCODText::getText(){ return TCOD_text_get(data); } void TCODText::reset(){ TCOD_text_reset(data); } #endif /* TCOD_CONSOLE_SUPPORT */ libtcod-1.6.4+dfsg/src/txtfield_c.c000066400000000000000000000501541321276576200171610ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #ifdef TCOD_CONSOLE_SUPPORT #include #include #include #include #include #define MAX_INT 0x7FFFFFFF typedef struct { int x, y; /* coordinates on parent console */ int w, h; /* textfield display size */ int max; /* maximum nb of characters */ int interval; /* cursor blinking interval */ int halfinterval; /* half of the above */ int ascii_cursor; /* cursor char. 0 if none */ int cursor_pos, sel_start,sel_end; /* cursor position in text, selection range */ int tab_size; /* tab size, if 0, no tab */ char * prompt; /* prompt to be displayed before the string */ int textx,texty; /* coordinate of start of text (after prompt) */ TCOD_console_t con; /* offscreen console that will contain the textfield */ bool input_continue; /* controls whether ENTER has been pressed */ int len; /* allocated size of the text */ int curlen; /* current length of the text */ TCOD_color_t back; /* background colour */ TCOD_color_t fore; /* foreground colour */ float transparency; /* background transparency */ bool multiline; /* multiline support ? */ char * text; /* the text itself */ } text_t; /* ctor */ TCOD_text_t TCOD_text_init (int x, int y, int w, int h, int max_chars) { text_t * data = (text_t*)calloc(sizeof(text_t),1); TCOD_IFNOT(w> 0 && h > 0) return data; data->x = x; data->y = y; data->w = w; data->h = h; data->multiline = (h > 1); data->max = (max_chars > 0 ? max_chars + 1 : MAX_INT); data->interval = 800; data->halfinterval = 400; data->ascii_cursor = 0; data->prompt = NULL; data->textx = data->texty = 0; data->con = TCOD_console_new(w,h); data->sel_start = MAX_INT; data->sel_end = -1; /* if (! data->multiline ) { data->max = MIN(w - data->textx,data->max); } else { data->max = MIN(w*(h-data->texty) - data->textx,data->max); } */ if (max_chars && max_chars > 0) data->max = max_chars; else data->max = data->w * data->h; data->input_continue = true; data->len = MIN(64,data->max); data->text = (char*)calloc(data->len,sizeof(char)); data->back.r = data->back.g = data->back.b = 0; data->fore.r = data->fore.g = data->fore.b = 255; data->transparency = 1.0f; return (TCOD_text_t)data; } TCOD_text_t TCOD_text_init2(int w, int h, int max_chars) { text_t * data = (text_t*)calloc(sizeof(text_t),1); TCOD_IFNOT(w> 0 && h > 0) return data; data->x = 0; data->y = 0; data->w = w; data->h = h; data->multiline = (h > 1); data->max = (max_chars > 0 ? max_chars + 1 : MAX_INT); data->interval = 800; data->halfinterval = 400; data->ascii_cursor = 0; data->prompt = NULL; data->textx = data->texty = 0; data->con = TCOD_console_new(w,h); data->sel_start = MAX_INT; data->sel_end = -1; /* if (! data->multiline ) { data->max = MIN(w - data->textx,data->max); } else { data->max = MIN(w*(h-data->texty) - data->textx,data->max); } */ if (max_chars && max_chars > 0) data->max = max_chars; else data->max = data->w * data->h; data->input_continue = true; data->len = MIN(64,data->max); data->text = (char*)calloc(data->len,sizeof(char)); data->back.r = data->back.g = data->back.b = 0; data->fore.r = data->fore.g = data->fore.b = 255; data->transparency = 1.0f; return (TCOD_text_t)data; } void TCOD_text_set_pos(TCOD_text_t txt, int x, int y) { text_t * data = (text_t*)txt; data->x=x; data->y=y; } /* set cursor and prompt */ void TCOD_text_set_properties (TCOD_text_t txt, int cursor_char, int blink_interval, const char * prompt, int tab_size) { text_t * data = (text_t*)txt; TCOD_IFNOT(data && data->con ) return; data->interval = blink_interval; data->halfinterval = (blink_interval > 0 ? blink_interval / 2 : 0); data->ascii_cursor = cursor_char; if (data->prompt) free(data->prompt); data->prompt = prompt ? TCOD_strdup(prompt) : NULL; data->textx = data->texty = 0; data->tab_size=tab_size; if ( prompt ) { const char *ptr=prompt; while (*ptr) { data->textx++; if ( *ptr == '\n' || data->textx == data->w) { data->textx=0;data->texty++; } ptr++; } } } /* set colours */ void TCOD_text_set_colors (TCOD_text_t txt, TCOD_color_t fore, TCOD_color_t back, float back_transparency) { text_t * data = (text_t*)txt; TCOD_IFNOT(data && data->con ) return; data->back = back; data->fore = fore; data->transparency = back_transparency; } /* increase the buffer size. internal function */ static void allocate(text_t *data) { char *tmp; data->len *= 2; tmp = (char*)calloc(data->len,sizeof(char)); memcpy(tmp,data->text,data->len/2); free(data->text); data->text = tmp; } /* insert a character at cursor position. internal function */ static void insertChar(text_t *data, char c) { char *ptr, *end; if (data->cursor_pos + 1 == data->max) { /* max size reached. replace the last char. don't increase text size */ *(data->text + data->cursor_pos -1) = c; return; } if (data->curlen + 1 == data->len ) allocate(data); ptr=data->text + data->cursor_pos; end=data->text + data->curlen; do { *(end+1) = *end; end--; } while ( end >= ptr ); *ptr = c; data->curlen++; data->cursor_pos++; } /* delete character at cursor position */ static void deleteChar(text_t *data) { char *ptr; if ( data->cursor_pos == 0 ) return; ptr=data->text + data->cursor_pos-1; do { *ptr = *(ptr+1); ptr++; } while (*ptr); if ( data->cursor_pos > 0 ) { data->cursor_pos--; data->curlen--; } } /* convert current cursor_pos into console coordinates. internal function */ static void get_cursor_coords(text_t *data, int *cx, int *cy) { char *ptr; if (data->multiline) { int curcount=data->cursor_pos; ptr=data->text; *cx = data->textx; *cy = data->texty; while (curcount > 0 && *ptr) { if ( *ptr == '\n') { *cx=0; (*cy)++; } else { (*cx)++; if ( *cx == data->w ) { *cx=0; (*cy)++; } } ptr++; curcount--; } } else { *cx = data->textx + data->cursor_pos; *cy = data->texty; } } /* check if the text does not overflow the textfield */ /* not working... static bool check_last_pos(text_t *data) { int count = strlen(data->text); int cx=data->textx; int cy=data->texty; char *ptr=data->text; while ( count > 0 ) { if ( *ptr == '\n') { cx=0; cy++; } else { cx++; if ( cx == data->w ) { cx=0; cy++; } } ptr++; count--; } return ( cy < data->h ); } */ /* set cursor_pos from coordinates. internal function */ static void set_cursor_pos(text_t *data, int cx, int cy, bool clamp) { if ( data->multiline ) { int curx=data->textx,cury=data->texty; char *ptr=data->text; int newpos=0; if ( clamp ) { cy=MAX(data->texty,cy); if ( cy == data->texty) cx = MAX(data->textx,cx); } /* find the right line */ while ( *ptr && cury < cy && cury < data->h ) { if (*ptr == '\n' || curx == data->w-1) { curx=0;cury++; } else curx++; ptr++; newpos++; } if ( cury >= data->h ) return; if ( cury == cy ) { /* check if cx can be reached */ while ( *ptr && curx < cx && *ptr != '\n') { ptr++; curx++; newpos++; } } data->cursor_pos = newpos; } else { int newpos = cx - data->textx + (cy - data->texty)*data->w; if ( clamp ) newpos = CLAMP(0,data->curlen,newpos); if ( newpos >= 0 && newpos <= data->curlen ) data->cursor_pos = newpos; } } /* decreases the selection range start */ static void selectStart(text_t *data, int oldpos, TCOD_key_t key) { if ( data->multiline && data->cursor_pos != oldpos ) { if ( key.shift ) { if ( data->sel_start > data->cursor_pos ) data->sel_start = data->cursor_pos; else data->sel_end = data->cursor_pos; } else { data->sel_start=MAX_INT; data->sel_end=-1; } } } /* increases the selection range end */ static void selectEnd(text_t *data, int oldpos, TCOD_key_t key) { if ( data->multiline && data->cursor_pos != oldpos ) { if ( key.shift ) { if ( data->sel_end < data->cursor_pos ) data->sel_end = data->cursor_pos; else data->sel_start = data->cursor_pos; } else { data->sel_start=MAX_INT; data->sel_end=-1; } } } enum { TYPE_SYMBOL, TYPE_ALPHANUM, TYPE_SPACE }; static const char symbols[]="&~\"#'{([-|`_\\^@)]=+}*/!:;.,?<>"; /* check whether a character is a space */ /* this is needed because cctype isspace() returns rubbish for many diacritics */ static bool is_space (int ch) { bool ret; switch (ch) { case ' ': case '\n': case '\r': case '\t': ret = true; break; default: ret = false; break; } return ret; } static void typecheck (int * type, int ch) { if (strchr(symbols,ch)) *type = TYPE_SYMBOL; else if (is_space(ch)) *type = TYPE_SPACE; else *type = TYPE_ALPHANUM; } /* go one word left */ static void previous_word(text_t *data) { /* current character type */ if ( data->cursor_pos > 0 ) { /* detect current char type (alphanum/space or symbol) */ char *ptr=data->text + data->cursor_pos - 1; int curtype, prevtype; typecheck(&curtype,*ptr); /* go back until char type changes from alphanumeric to something else */ do { data->cursor_pos--; ptr--; prevtype = curtype; typecheck(&curtype,*ptr); } while ( data->cursor_pos > 0 && !(curtype != TYPE_ALPHANUM && prevtype == TYPE_ALPHANUM)); } } /* go one word right */ static void next_word(text_t *data) { /* current character type */ if ( data->text[data->cursor_pos] ) { /* detect current char type (alphanum/space or symbol) */ char *ptr=data->text + data->cursor_pos; int curtype, prevtype; typecheck(&curtype,*ptr); /* go forth until char type changes from non alphanumeric to alphanumeric */ do { data->cursor_pos++; ptr++; prevtype = curtype; typecheck(&curtype,*ptr); } while ( *ptr && !(curtype == TYPE_ALPHANUM && prevtype != TYPE_ALPHANUM)); } } /* erase the selected text */ static void deleteSelection(text_t *data) { int count = data->sel_end-data->sel_start; data->cursor_pos = data->sel_start+1; while ( count > 0 ) { deleteChar(data); count--; data->cursor_pos++; } data->cursor_pos--; data->sel_start=MAX_INT; data->sel_end=-1; } /* copy selected text to clipboard */ static void copy(text_t *data) { if ( data->sel_end - data->sel_start > 0 ) { char *clipbuf = (char*)calloc(data->sel_end - data->sel_start+1,1); char *ptr=clipbuf; int i; for (i=data->sel_start; i != data->sel_end; i++) { *ptr++ = data->text[i]; } TCOD_sys_clipboard_set(clipbuf); free(clipbuf); } } /* cut selected text to clipboard */ static void cut(text_t *data) { if ( data->sel_end - data->sel_start > 0 ) { char *clipbuf = (char*)calloc(data->sel_end - data->sel_start+1,1); char *ptr=clipbuf; int i; for (i=data->sel_start; i != data->sel_end; i++) { *ptr++ = data->text[i]; } TCOD_sys_clipboard_set(clipbuf); free(clipbuf); deleteSelection(data); } } /* paste from clipboard */ static void paste(text_t *data) { char *clipbuf=TCOD_sys_clipboard_get(); if ( clipbuf ) { if ( data->sel_start != MAX_INT ) { deleteSelection(data); } while (*clipbuf) { insertChar(data,*clipbuf++); } } } /* update returns false if enter has been pressed, true otherwise */ bool TCOD_text_update (TCOD_text_t txt, TCOD_key_t key) { int cx,cy,oldpos; text_t * data = (text_t*)txt; TCOD_IFNOT(data && data->con ) return false; oldpos = data->cursor_pos; /* for real-time keyboard : only on key release */ if ( key.pressed ) { /* process keyboard input */ switch (key.vk) { case TCODK_BACKSPACE: /* get rid of the last character */ if ( data->sel_start != MAX_INT ) { deleteSelection(data); } else { deleteChar(data); } break; case TCODK_DELETE: if ( key.shift ) { /* SHIFT-DELETE : cut to clipboard */ cut(data); } else { if ( data->sel_start != MAX_INT ) { deleteSelection(data); } else if ( data->text[data->cursor_pos] ) { data->cursor_pos++; deleteChar(data); } } break; /* shift + arrow / home / end = selection */ /* ctrl + arrow = word skipping. ctrl + shift + arrow = word selection */ case TCODK_LEFT: if ( data->multiline && key.shift && data->sel_end == -1) { data->sel_end = data->cursor_pos; } if ( data->cursor_pos > 0 ) { if ( key.lctrl || key.rctrl ) { previous_word(data); } else data->cursor_pos--; selectStart(data,oldpos,key); } break; case TCODK_RIGHT: if ( data->multiline && key.shift && data->sel_start == MAX_INT ) { data->sel_start = data->cursor_pos; } if ( data->text[data->cursor_pos] ) { if ( key.lctrl || key.rctrl ) { next_word(data); } else data->cursor_pos++; selectEnd(data,oldpos,key); } break; case TCODK_UP : get_cursor_coords(data,&cx,&cy); if ( data->multiline && key.shift && data->sel_end == -1) { data->sel_end = data->cursor_pos; } set_cursor_pos(data,cx,cy-1,false); selectStart(data,oldpos,key); break; case TCODK_DOWN : get_cursor_coords(data,&cx,&cy); if ( data->multiline && key.shift && data->sel_start == MAX_INT ) { data->sel_start = data->cursor_pos; } set_cursor_pos(data,cx,cy+1,false); selectEnd(data,oldpos,key); break; case TCODK_HOME: get_cursor_coords(data,&cx,&cy); if ( data->multiline && key.shift && data->sel_end == -1) { data->sel_end = data->cursor_pos; } if ( key.lctrl || key.rctrl ) { set_cursor_pos(data,0,0,true); } else { set_cursor_pos(data,0,cy,true); } selectStart(data,oldpos,key); break; case TCODK_END: get_cursor_coords(data,&cx,&cy); if ( data->multiline && key.shift && data->sel_start == MAX_INT ) { data->sel_start = data->cursor_pos; } if ( key.lctrl || key.rctrl ) { set_cursor_pos(data,data->w,data->h,true); } else { set_cursor_pos(data,data->w-1,cy,true); } selectEnd(data,oldpos,key); break; case TCODK_ENTER: /* validate input */ case TCODK_KPENTER: if ( data->sel_start != MAX_INT ) { deleteSelection(data); } if ( data->multiline ) { get_cursor_coords(data,&cx,&cy); if ( cy < data->h-1 ) insertChar(data,'\n'); } else { data->input_continue = false; } break; case TCODK_TAB : if (data->tab_size ) { int count=data->tab_size; if ( data->sel_start != MAX_INT ) { deleteSelection(data); } while ( count > 0 ) { insertChar(data,' '); count--; } } break; default: { /* append a new character */ if ( (key.c == 'c' || key.c=='C' || key.vk == TCODK_INSERT) && (key.lctrl || key.rctrl) ) { /* CTRL-C or CTRL-INSERT : copy to clipboard */ copy(data); } else if ( (key.c == 'x' || key.c=='X') && (key.lctrl || key.rctrl) ) { /* CTRL-X : cut to clipboard */ cut(data); } else if ( ((key.c == 'v' || key.c=='V') && (key.lctrl || key.rctrl)) || ( key.vk == TCODK_INSERT && key.shift ) ) { /* CTRL-V or SHIFT-INSERT : paste from clipboard */ paste(data); } else if (key.c > 31) { if ( data->sel_start != MAX_INT ) { deleteSelection(data); } insertChar(data,(char)(key.c)); } break; } } } return data->input_continue; } /* renders the textfield */ void TCOD_text_render (TCOD_text_t txt, TCOD_console_t con) { text_t * data = (text_t*)txt; uint32_t time; bool cursor_on; char back=0; int curx,cury,cursorx,cursory, curpos; char *ptr; TCOD_IFNOT(data && data->con ) return; time = TCOD_sys_elapsed_milli(); cursor_on = (int)( time % data->interval ) > data->halfinterval; TCOD_console_set_default_background(data->con, data->back); TCOD_console_set_default_foreground(data->con, data->fore); TCOD_console_clear(data->con); /* compute cursor position */ get_cursor_coords(data,&cursorx,&cursory); if ( cursor_on && data->ascii_cursor) { /* save the character under cursor position */ back = data->text[data->cursor_pos]; data->text[data->cursor_pos] = data->ascii_cursor; } /* render prompt */ if (data->prompt) TCOD_console_print_rect_ex(data->con,0,0,data->w,data->h,TCOD_BKGND_SET,TCOD_LEFT,"%s",data->prompt); /* render text */ curx=data->textx; cury=data->texty; ptr=data->text; curpos=0; while (*ptr) { if ( *ptr == '\n') { if ( (curx == 0 || curpos == 0 ) && curpos >= data->sel_start && curpos < data->sel_end ) { /* inverted colors for selected empty lines */ TCOD_console_set_char_background(data->con, curx, cury, data->fore, TCOD_BKGND_SET); TCOD_console_set_char_foreground(data->con, curx, cury, data->back); } curx=0; cury++; } else { if ( curpos >= data->sel_start && curpos < data->sel_end ) { /* inverted colors for selection */ TCOD_console_set_char_background(data->con, curx, cury, data->fore, TCOD_BKGND_SET); TCOD_console_set_char_foreground(data->con, curx, cury, data->back); } TCOD_console_set_char(data->con,curx,cury,*ptr); curx++; if ( curx == data->w ) { curx=0; cury++; } } ptr++; curpos++; } if ( cursor_on ) { if ( data->ascii_cursor) { /* restore the character under cursor */ data->text[data->cursor_pos] = back; } else { /* invert colors at cursor position */ TCOD_console_set_char_background(data->con,cursorx,cursory,data->fore,TCOD_BKGND_SET); TCOD_console_set_char_foreground(data->con,cursorx,cursory,data->back); } } else if (! cursor_on && ! data->ascii_cursor && data->multiline ) { /* normal colors for cursor ( might be inside selection ) */ TCOD_console_set_char_background(data->con,cursorx,cursory,data->back,TCOD_BKGND_SET); TCOD_console_set_char_foreground(data->con,cursorx,cursory,data->fore); } TCOD_console_blit(data->con,0,0,data->w,data->h,con,data->x,data->y,1.0f,data->transparency); } /* returns the text currently stored in the textfield object */ const char * TCOD_text_get (TCOD_text_t txt) { text_t * data = (text_t*)txt; TCOD_IFNOT(data && data->con ) return ""; return data->text; } /* resets the text initial state */ void TCOD_text_reset (TCOD_text_t txt) { text_t * data = (text_t*)txt; TCOD_IFNOT(data && data->con ) return; memset(data->text,'\0',data->len); data->curlen = 0; data->cursor_pos = 0; data->sel_start = MAX_INT; data->sel_end = -1; data->input_continue = true; } /* destructor */ void TCOD_text_delete (TCOD_text_t txt) { text_t * data = (text_t*)txt; TCOD_IFNOT(data && data->con ) return; if ( data->text ) free(data->text); if ( data->prompt ) free(data->prompt); TCOD_console_delete(data->con); free(data); } #endif /* TCOD_CONSOLE_SUPPORT */libtcod-1.6.4+dfsg/src/wrappers.c000066400000000000000000000252551321276576200167030ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #define RED_MASK 0x0000FF #define GREEN_MASK 0x00FF00 #define BLUE_MASK 0xFF0000 TCOD_color_t int_to_color (colornum_t col) { TCOD_color_t ret; ret.r = col & RED_MASK; ret.g = (col & GREEN_MASK) >> 8; ret.b = (col & BLUE_MASK) >> 16; return ret; } #define color_to_int(col) (int)(((int)((col).b) << 16) | ((col).g << 8) | (col).r) bool TCOD_color_equals_wrapper (colornum_t c1, colornum_t c2) { return TCOD_color_equals (int_to_color(c1), int_to_color(c2)); } colornum_t TCOD_color_add_wrapper (colornum_t c1, colornum_t c2) { return color_to_int(TCOD_color_add (int_to_color(c1), int_to_color(c2))); } colornum_t TCOD_color_subtract_wrapper (colornum_t c1, colornum_t c2) { return color_to_int(TCOD_color_subtract (int_to_color(c1), int_to_color(c2))); } colornum_t TCOD_color_multiply_wrapper (colornum_t c1, colornum_t c2) { return color_to_int(TCOD_color_multiply (int_to_color(c1), int_to_color(c2))); } colornum_t TCOD_color_multiply_scalar_wrapper (colornum_t c1, float value) { return color_to_int(TCOD_color_multiply_scalar (int_to_color(c1), value)); } colornum_t TCOD_color_lerp_wrapper(colornum_t c1, colornum_t c2, float coef) { return color_to_int(TCOD_color_lerp (int_to_color(c1),int_to_color(c2), coef)); } void TCOD_color_get_HSV_wrapper(colornum_t c,float * h, float * s, float * v) { TCOD_color_get_HSV (int_to_color(c), h, s, v); } float TCOD_color_get_hue_wrapper (colornum_t c) { return TCOD_color_get_hue(int_to_color(c)); } float TCOD_color_get_saturation_wrapper (colornum_t c) { return TCOD_color_get_saturation(int_to_color(c)); } float TCOD_color_get_value_wrapper (colornum_t c) { return TCOD_color_get_value(int_to_color(c)); } #ifdef TCOD_CONSOLE_SUPPORT colornum_t TCOD_console_get_default_background_wrapper(TCOD_console_t con) { return color_to_int(TCOD_console_get_default_background (con)); } colornum_t TCOD_console_get_default_foreground_wrapper(TCOD_console_t con) { return color_to_int(TCOD_console_get_default_foreground (con)); } void TCOD_console_set_default_background_wrapper(TCOD_console_t con, colornum_t col) { TCOD_console_set_default_background (con, int_to_color(col)); } void TCOD_console_set_default_foreground_wrapper(TCOD_console_t con, colornum_t col) { TCOD_console_set_default_foreground (con, int_to_color(col)); } colornum_t TCOD_console_get_char_foreground_wrapper(TCOD_console_t con, int x, int y) { return color_to_int(TCOD_console_get_char_foreground (con, x, y)); } colornum_t TCOD_console_get_char_background_wrapper(TCOD_console_t con, int x, int y) { return color_to_int(TCOD_console_get_char_background (con, x, y)); } void TCOD_console_set_char_background_wrapper(TCOD_console_t con,int x, int y, colornum_t col, TCOD_bkgnd_flag_t flag) { TCOD_console_set_char_background (con, x, y, int_to_color(col), flag); } void TCOD_console_set_char_foreground_wrapper(TCOD_console_t con,int x, int y, colornum_t col) { TCOD_console_set_char_foreground (con, x, y, int_to_color(col)); } void TCOD_console_put_char_ex_wrapper(TCOD_console_t con, int x, int y, int c, colornum_t fore, colornum_t back) { TCOD_console_put_char_ex (con, x, y, c, int_to_color(fore), int_to_color(back)); } void TCOD_console_set_fade_wrapper(uint8_t val, colornum_t fade) { TCOD_console_set_fade (val, int_to_color(fade)); } void TCOD_console_fill_background(TCOD_console_t con, int *r, int *g, int *b) { TCOD_console_data_t *dat = con ? (TCOD_console_data_t *)con : TCOD_ctx.root; int i; TCOD_color_t *curcolor = TCOD_image_get_colors(dat->bg_colors); for (i = 0; i < dat->w*dat->h; i++) { curcolor->r = *r; curcolor->g = *g; curcolor->b = *b; curcolor++; r++; g++; b++; } } void TCOD_console_fill_foreground(TCOD_console_t con, int *r, int *g, int *b) { TCOD_console_data_t *dat = con ? (TCOD_console_data_t *)con : TCOD_ctx.root; int i; TCOD_color_t *curcolor = TCOD_image_get_colors(dat->fg_colors); for (i = 0; i < dat->w*dat->h; i++) { curcolor->r = *r; curcolor->g = *g; curcolor->b = *b; curcolor++; r++; g++; b++; } } void TCOD_console_fill_char(TCOD_console_t con, int *arr) { TCOD_console_data_t *dat = con ? (TCOD_console_data_t *)con : TCOD_ctx.root; int i; for (i = 0; i < dat->w*dat->h; i++) { dat->ch_array[i] = arr[i]; } } colornum_t TCOD_console_get_fading_color_wrapper () { return color_to_int(TCOD_console_get_fading_color()); } void TCOD_console_set_color_control_wrapper(TCOD_colctrl_t con, colornum_t fore, colornum_t back) { TCOD_console_set_color_control (con, int_to_color(fore), int_to_color(back)); } #endif /* TCOD_CONSOLE_SUPPORT */ #ifdef TCOD_IMAGE_SUPPORT void TCOD_image_clear_wrapper(TCOD_image_t image, colornum_t color) { TCOD_image_clear (image, int_to_color(color)); } colornum_t TCOD_image_get_pixel_wrapper(TCOD_image_t image, int x, int y) { return color_to_int(TCOD_image_get_pixel (image, x, y)); } colornum_t TCOD_image_get_mipmap_pixel_wrapper(TCOD_image_t image, float x0,float y0, float x1, float y1) { return color_to_int(TCOD_image_get_mipmap_pixel (image, x0, y0, x1, y1)); } void TCOD_image_put_pixel_wrapper(TCOD_image_t image,int x, int y, colornum_t col) { TCOD_image_put_pixel (image, x, y, int_to_color( col)); } void TCOD_image_set_key_color_wrapper(TCOD_image_t image, colornum_t key_color) { TCOD_image_set_key_color (image, int_to_color(key_color)); } #endif /* TCOD_IMAGE_SUPPORT */ #ifdef TCOD_CONSOLE_SUPPORT bool TCOD_console_check_for_keypress_wrapper (TCOD_key_t *holder, int flags) { *holder = TCOD_console_check_for_keypress(flags); return (holder->vk != TCODK_NONE); } void TCOD_console_wait_for_keypress_wrapper (TCOD_key_t *holder, bool flush) { *holder = TCOD_console_wait_for_keypress(flush); } void TCOD_mouse_get_status_wrapper(TCOD_mouse_t *mouse) { *mouse=TCOD_mouse_get_status(); } /* Routines to draw hlines, vlines and frames using the double-lined * characters. */ void TCOD_console_double_hline(TCOD_console_t con,int x,int y, int l, TCOD_bkgnd_flag_t flag) { int i; for (i=x; i< x+l; i++) TCOD_console_put_char(con,i,y,TCOD_CHAR_DHLINE,flag); } void TCOD_console_double_vline(TCOD_console_t con,int x,int y, int l, TCOD_bkgnd_flag_t flag) { int i; for (i=y; i< y+l; i++) TCOD_console_put_char(con,x,i,TCOD_CHAR_DVLINE,flag); } void TCOD_console_print_double_frame(TCOD_console_t con,int x,int y,int w,int h, bool empty, TCOD_bkgnd_flag_t flag, const char *fmt, ...) { TCOD_console_data_t *dat = con ? (TCOD_console_data_t *)con : TCOD_ctx.root; TCOD_console_put_char(con,x,y,TCOD_CHAR_DNW,flag); TCOD_console_put_char(con,x+w-1,y,TCOD_CHAR_DNE,flag); TCOD_console_put_char(con,x,y+h-1,TCOD_CHAR_DSW,flag); TCOD_console_put_char(con,x+w-1,y+h-1,TCOD_CHAR_DSE,flag); TCOD_console_double_hline(con,x+1,y,w-2, flag); TCOD_console_double_hline(con,x+1,y+h-1,w-2, flag); TCOD_console_double_vline(con,x,y+1,h-2, flag); TCOD_console_double_vline(con,x+w-1,y+1,h-2, flag); if ( h > 2 ) { TCOD_console_vline(con,x,y+1,h-2,flag); TCOD_console_vline(con,x+w-1,y+1,h-2,flag); if ( empty ) { TCOD_console_rect(con,x+1,y+1,w-2,h-2,true,flag); } } if (fmt) { va_list ap; int xs; TCOD_color_t tmp; char *title; va_start(ap,fmt); title = TCOD_console_vsprint(fmt,ap); va_end(ap); title[w-3]=0; /* truncate if needed */ xs = x + (w-(int)strlen(title)-2)/2; tmp=dat->back; /* swap colors */ dat->back=dat->fore; dat->fore=tmp; TCOD_console_print_ex(con,xs,y,TCOD_BKGND_SET,TCOD_LEFT," %s ",title); tmp=dat->back; /* swap colors */ dat->back=dat->fore; dat->fore=tmp; } } char *TCOD_console_print_return_string(TCOD_console_t con,int x,int y, int rw, int rh, TCOD_bkgnd_flag_t flag, TCOD_alignment_t align, char *msg, bool can_split, bool count_only) { TCOD_console_print_internal(con,x,y,rw,rh,flag,align,msg,can_split,count_only); return msg; } #endif /* TCOD_CONSOLE_SUPPORT */ colornum_t TCOD_parser_get_color_property_wrapper(TCOD_parser_t parser, const char *name) { return color_to_int(TCOD_parser_get_color_property(parser,name)); } int TCOD_namegen_get_nb_sets_wrapper(void) { TCOD_list_t l=TCOD_namegen_get_sets(); int nb = TCOD_list_size(l); TCOD_list_delete(l); return nb; } void TCOD_namegen_get_sets_wrapper(char **sets) { TCOD_list_t l=TCOD_namegen_get_sets(); char **it; int i=0; for (it=(char**)TCOD_list_begin(l); it != (char **)TCOD_list_end(l); it++) { sets[i++]=*it; } } #ifdef TCOD_SDL2 int TCOD_sys_get_current_resolution_x() { int x, y; TCOD_sys_get_current_resolution(&x, &y); return x; } int TCOD_sys_get_current_resolution_y() { int x, y; TCOD_sys_get_current_resolution(&x, &y); return y; } #endif #ifdef TCOD_CONSOLE_SUPPORT void TCOD_console_set_key_color_wrapper (TCOD_console_t con, colornum_t c) { TCOD_console_set_key_color(con, int_to_color(c)); } #endif libtcod-1.6.4+dfsg/src/zip.cpp000066400000000000000000000067701321276576200162030ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include TCODZip::TCODZip() { data=TCOD_zip_new(); } TCODZip::~TCODZip() { TCOD_zip_delete(data); } void TCODZip::putChar(char val) { TCOD_zip_put_char(data,val); } void TCODZip::putInt(int val) { TCOD_zip_put_int(data,val); } void TCODZip::putFloat(float val) { TCOD_zip_put_float(data,val); } void TCODZip::putString(const char *val) { TCOD_zip_put_string(data,val); } void TCODZip::putData(int nbBytes, const void *pdata) { TCOD_zip_put_data(data,nbBytes,pdata); } void TCODZip::putColor(const TCODColor *val) { TCOD_color_t col; col.r=val->r; col.g=val->g; col.b=val->b; TCOD_zip_put_color(data,col); } #ifdef TCOD_IMAGE_SUPPORT void TCODZip::putImage(const TCODImage *val) { TCOD_zip_put_image(data,val->data); } #endif #ifdef TCOD_CONSOLE_SUPPORT void TCODZip::putConsole(const TCODConsole *val) { TCOD_zip_put_console(data,val->data); } #endif int TCODZip::saveToFile(const char *filename) { return TCOD_zip_save_to_file(data,filename); } int TCODZip::loadFromFile(const char *filename) { return TCOD_zip_load_from_file(data,filename); } char TCODZip::getChar() { return TCOD_zip_get_char(data); } int TCODZip::getInt() { return TCOD_zip_get_int(data); } float TCODZip::getFloat() { return TCOD_zip_get_float(data); } const char *TCODZip::getString() { return TCOD_zip_get_string(data); } int TCODZip::getData(int nbBytes, void *pdata) { return TCOD_zip_get_data(data,nbBytes,pdata); } TCODColor TCODZip::getColor() { return TCODColor(TCOD_zip_get_color(data)); } #ifdef TCOD_IMAGE_SUPPORT TCODImage *TCODZip::getImage() { return new TCODImage(TCOD_zip_get_image(data)); } #endif #ifdef TCOD_CONSOLE_SUPPORT TCODConsole *TCODZip::getConsole() { return new TCODConsole(TCOD_zip_get_console(data)); } #endif uint32_t TCODZip::getCurrentBytes() const { return TCOD_zip_get_current_bytes(data); } uint32_t TCODZip::getRemainingBytes() const { return TCOD_zip_get_remaining_bytes(data); } void TCODZip::skipBytes(uint32_t nbBytes) { TCOD_zip_skip_bytes(data,nbBytes); } libtcod-1.6.4+dfsg/src/zip_c.c000066400000000000000000000270001321276576200161320ustar00rootroot00000000000000/* * libtcod 1.6.4 * Copyright (c) 2008,2009,2010,2012,2013,2016,2017 Jice & Mingos & rmtew * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of Jice or Mingos may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JICE, MINGOS AND RMTEW ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JICE, MINGOS OR RMTEW BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include typedef struct { TCOD_list_t buffer; /* list */ uintptr_t ibuffer; /* byte buffer. bytes are send into buffer 4 by 4 (32 bits OS) or 8 by 8(64 bits OS) */ int isize; /* number of bytes in ibuffer */ int bsize; /* number of bytes in buffer */ int offset; /* current reading position */ } zip_data_t; TCOD_zip_t TCOD_zip_new(void) { zip_data_t *ret=(zip_data_t *)calloc(sizeof(zip_data_t),1); return (TCOD_zip_t)ret; } void TCOD_zip_delete(TCOD_zip_t pzip) { zip_data_t *zip=(zip_data_t *)pzip; if ( zip->buffer != NULL ) TCOD_list_delete(zip->buffer); free(zip); } /* output interface */ void TCOD_zip_put_char(TCOD_zip_t pzip, char val) { zip_data_t *zip=(zip_data_t *)pzip; uintptr_t iv=(uintptr_t)(uint8_t)val; /* store one byte in ibuffer */ switch (zip->isize) { case 0 : zip->ibuffer|=iv; break; case 1 : zip->ibuffer|=(iv<<8); break; case 2 : zip->ibuffer|=(iv<<16); break; case 3 : zip->ibuffer|=(iv<<24); break; #ifdef TCOD_64BITS /* for 64 bits OS */ case 4 : zip->ibuffer|=(iv<<32); break; case 5 : zip->ibuffer|=(iv<<40); break; case 6 : zip->ibuffer|=(iv<<48); break; case 7 : zip->ibuffer|=(iv<<56); break; #endif } zip->isize++; zip->bsize++; if (zip->isize == sizeof(uintptr_t) ) { /* ibuffer full. send it to buffer */ if (!zip->buffer) zip->buffer=TCOD_list_new(); TCOD_list_push(zip->buffer,(void *)zip->ibuffer); zip->isize = 0; zip->ibuffer = 0; } } void TCOD_zip_put_int(TCOD_zip_t pzip, int val) { #ifndef TCOD_64BITS zip_data_t *zip=(zip_data_t *)pzip; if ( zip->isize == 0 ) { /* the buffer is padded. read 4 bytes */ if (!zip->buffer) zip->buffer=TCOD_list_new(); TCOD_list_push(zip->buffer,(void *)val); zip->bsize += sizeof(uintptr_t); } else { #endif /* the buffer is not padded. read 4x1 byte */ TCOD_zip_put_char(pzip,(char)(val&0xFF)); TCOD_zip_put_char(pzip,(char)((val&0xFF00)>>8)); TCOD_zip_put_char(pzip,(char)((val&0xFF0000)>>16)); TCOD_zip_put_char(pzip,(char)((val&0xFF000000)>>24)); #ifndef TCOD_64BITS } #endif } void TCOD_zip_put_float(TCOD_zip_t pzip, float val) { TCOD_zip_put_int(pzip,* (int *)(&val) ); } void TCOD_zip_put_string(TCOD_zip_t pzip, const char *val) { if (val == NULL) TCOD_zip_put_int(pzip,-1); else { size_t l=strlen(val),i; TCOD_zip_put_int(pzip,(int)l); for (i=0; i <= l; i++) TCOD_zip_put_char(pzip,val[i]); } } void TCOD_zip_put_data(TCOD_zip_t pzip, int nbBytes, const void *data) { if (data == NULL) TCOD_zip_put_int(pzip,-1); else { char *val=(char *)data; int i; TCOD_zip_put_int(pzip,nbBytes); for (i=0; i< nbBytes; i++) TCOD_zip_put_char(pzip,val[i]); } } void TCOD_zip_put_color(TCOD_zip_t zip, const TCOD_color_t val) { TCOD_zip_put_char(zip,val.r); TCOD_zip_put_char(zip,val.g); TCOD_zip_put_char(zip,val.b); } #ifdef TCOD_IMAGE_SUPPORT void TCOD_zip_put_image(TCOD_zip_t zip, const TCOD_image_t val) { int w,h,x,y; TCOD_image_get_size(val, &w,&h); TCOD_zip_put_int(zip,w); TCOD_zip_put_int(zip,h); for (y=0; y < h; y++) { for (x=0; x < w; x++ ) { TCOD_zip_put_color(zip,TCOD_image_get_pixel(val,x,y)); } } } #endif #ifdef TCOD_CONSOLE_SUPPORT void TCOD_zip_put_console(TCOD_zip_t zip, const TCOD_console_t val) { int w,h,x,y; w=TCOD_console_get_width(val); h=TCOD_console_get_height(val); TCOD_zip_put_int(zip,w); TCOD_zip_put_int(zip,h); for (y=0; y < h; y++) { for (x=0; x < w; x++ ) { TCOD_zip_put_char(zip,TCOD_console_get_char(val,x,y)); TCOD_zip_put_color(zip,TCOD_console_get_char_foreground(val,x,y)); TCOD_zip_put_color(zip,TCOD_console_get_char_background(val,x,y)); } } } #endif int TCOD_zip_save_to_file(TCOD_zip_t pzip, const char *filename) { zip_data_t *zip=(zip_data_t *)pzip; gzFile f=gzopen(filename,"wb"); int l=zip->bsize, ret; void *buf; if (!f) return 0; gzwrite(f,&l,sizeof(int)); if (l==0) { gzclose(f); return 0; } if ( zip->isize > 0 ) { /* send remaining bytes from ibuffer to buffer */ if (!zip->buffer) zip->buffer=TCOD_list_new(); TCOD_list_push(zip->buffer,(void *)zip->ibuffer); zip->isize = 0; zip->ibuffer = 0; } buf=(void *)TCOD_list_begin(zip->buffer); ret=gzwrite(f,buf,l); if (ret != l) { gzclose(f); return 0; } ret=gzclose(f); if (ret != Z_OK) return 0; return l; } /* input interface */ int TCOD_zip_load_from_file(TCOD_zip_t pzip, const char *filename) { zip_data_t *zip=(zip_data_t *)pzip; gzFile f=gzopen(filename,"rb"); int l,lread; void *buf; int wordsize=sizeof(uintptr_t); if (!f) return 0; gzread(f,&l,sizeof(int)); if (l==0) { gzclose(f); return 0; } if ( zip->buffer) { TCOD_list_delete(zip->buffer); memset(zip,0,sizeof(zip_data_t)); } zip->buffer=TCOD_list_allocate((l+wordsize-1)/wordsize); TCOD_list_set_size(zip->buffer,(l+wordsize-1)/wordsize); buf=(void *)TCOD_list_begin(zip->buffer); lread=gzread(f,buf,l); gzclose(f); return lread == 0 ? l : lread; } char TCOD_zip_get_char(TCOD_zip_t pzip) { zip_data_t *zip=(zip_data_t *)pzip; char c=0; if ( zip->isize == 0 ) { /* ibuffer is empty. get 4 or 8 new bytes from buffer */ zip->ibuffer=(uintptr_t)TCOD_list_get(zip->buffer,zip->offset); zip->offset++; zip->isize=sizeof(uintptr_t); } /* read one byte from ibuffer */ #ifdef TCOD_64BITS switch(zip->isize) { case 8: c= zip->ibuffer&0xFFL; break; case 7: c= (zip->ibuffer>>8) & 0xFFL; break; case 6: c= (zip->ibuffer>>16) & 0xFFL; break; case 5: c= (zip->ibuffer>>24) & 0xFFL; break; case 4: c= (zip->ibuffer>>32) & 0xFFL; break; case 3: c= (zip->ibuffer>>40) & 0xFFL; break; case 2: c= (zip->ibuffer>>48) & 0xFFL; break; case 1: c= (zip->ibuffer>>56) & 0xFFL; break; } #else switch(zip->isize) { case 4: c= (char)(zip->ibuffer&0xFF); break; case 3: c= (char)((zip->ibuffer&0xFF00)>>8); break; case 2: c= (char)((zip->ibuffer&0xFF0000)>>16); break; case 1: c= (char)((zip->ibuffer&0xFF000000)>>24); break; } #endif zip->isize--; return c; } int TCOD_zip_get_int(TCOD_zip_t pzip) { #ifndef TCOD_64BITS zip_data_t *zip=(zip_data_t *)pzip; if ( zip->isize == 0 ) { /* buffer is padded. read 4 bytes */ int i=(int)TCOD_list_get(zip->buffer,zip->offset); zip->offset++; return i; } else { #endif /* buffer is not padded. read 4x 1 byte */ uint32_t i1=(uint32_t)(uint8_t)TCOD_zip_get_char(pzip); uint32_t i2=(uint32_t)(uint8_t)TCOD_zip_get_char(pzip); uint32_t i3=(uint32_t)(uint8_t)TCOD_zip_get_char(pzip); uint32_t i4=(uint32_t)(uint8_t)TCOD_zip_get_char(pzip); return i1 | (i2<<8) | (i3<<16) | (i4<<24); #ifndef TCOD_64BITS } #endif } float TCOD_zip_get_float(TCOD_zip_t pzip) { int i=TCOD_zip_get_int(pzip); return *(float *)(&i); } TCOD_color_t TCOD_zip_get_color(TCOD_zip_t pzip) { TCOD_color_t col; col.r=TCOD_zip_get_char(pzip); col.g=TCOD_zip_get_char(pzip); col.b=TCOD_zip_get_char(pzip); return col; } const char *TCOD_zip_get_string(TCOD_zip_t pzip) { zip_data_t *zip=(zip_data_t *)pzip; int l=TCOD_zip_get_int(pzip); const char *ret=(const char *)TCOD_list_begin(zip->buffer); int boffset; /* offset in bytes */ if ( l == -1 ) return NULL; boffset=zip->offset*sizeof(uintptr_t)-zip->isize; /* current offset */ ret += boffset; /* the string address in buffer */ boffset += l+1; /* new offset */ /* update ibuffer */ zip->offset = (boffset+sizeof(uintptr_t)-1)/sizeof(uintptr_t); zip->isize = boffset%sizeof(uintptr_t); if ( zip->isize != 0 ) { zip->isize=sizeof(uintptr_t)-zip->isize; zip->ibuffer=(uintptr_t)TCOD_list_get(zip->buffer,zip->offset-1); } return ret; } int TCOD_zip_get_data(TCOD_zip_t pzip, int nbBytes, void *data) { zip_data_t *zip=(zip_data_t *)pzip; int l=TCOD_zip_get_int(pzip),i; const char *in=(const char *)TCOD_list_begin(zip->buffer); char *out=(char *)data; int boffset; /* offset in bytes */ if ( l == -1 ) return 0; boffset=zip->offset*sizeof(uintptr_t)-zip->isize; /* current offset */ in += boffset; /* the data address in buffer */ /* copy it to data */ for (i=0; i < MIN(l,nbBytes); i++ ) { *(out++)=*(in++); boffset++; } /* update ibuffer */ zip->offset = (boffset+sizeof(uintptr_t)-1)/sizeof(uintptr_t); zip->isize = boffset%sizeof(uintptr_t); if ( zip->isize != 0 ) { zip->isize=sizeof(uintptr_t)-zip->isize; zip->ibuffer=(uintptr_t)TCOD_list_get(zip->buffer,zip->offset-1); } return l; } #ifdef TCOD_IMAGE_SUPPORT TCOD_image_t TCOD_zip_get_image(TCOD_zip_t pzip) { TCOD_image_t ret; int w,h,x,y; w=TCOD_zip_get_int(pzip); h=TCOD_zip_get_int(pzip); ret=TCOD_image_new(w,h); for (y=0; y < h; y++) { for (x=0; x < w; x++ ) { TCOD_image_put_pixel(ret, x,y,TCOD_zip_get_color(pzip)); } } return ret; } #endif #ifdef TCOD_CONSOLE_SUPPORT TCOD_console_t TCOD_zip_get_console(TCOD_zip_t pzip) { TCOD_console_t ret; int w,h,x,y; w=TCOD_zip_get_int(pzip); h=TCOD_zip_get_int(pzip); ret=TCOD_console_new(w,h); for (y=0; y < h; y++) { for (x=0; x < w; x++ ) { TCOD_console_set_char(ret, x,y,TCOD_zip_get_char(pzip)); TCOD_console_set_char_foreground(ret, x,y,TCOD_zip_get_color(pzip)); TCOD_console_set_char_background(ret, x,y,TCOD_zip_get_color(pzip), TCOD_BKGND_SET); } } return ret; } #endif uint32_t TCOD_zip_get_current_bytes(TCOD_zip_t pzip) { zip_data_t *zip=(zip_data_t *)pzip; if (!zip->buffer) zip->buffer=TCOD_list_new(); return TCOD_list_size(zip->buffer)*sizeof(uintptr_t)+zip->isize; } uint32_t TCOD_zip_get_remaining_bytes(TCOD_zip_t pzip) { zip_data_t *zip=(zip_data_t *)pzip; if (!zip->buffer) zip->buffer=TCOD_list_new(); return (TCOD_list_size(zip->buffer) - zip->offset) * sizeof(uintptr_t) + zip->isize; } void TCOD_zip_skip_bytes(TCOD_zip_t pzip, uint32_t nbBytes) { zip_data_t *zip=(zip_data_t *)pzip; uint32_t boffset=zip->offset*sizeof(uintptr_t)-zip->isize+ nbBytes; /* new offset */ TCOD_IFNOT(boffset <= TCOD_list_size(zip->buffer)*sizeof(uintptr_t)) return; zip->offset = (boffset+sizeof(uintptr_t)-1)/sizeof(uintptr_t); zip->isize = boffset%sizeof(uintptr_t); if ( zip->isize != 0 ) { zip->isize=sizeof(uintptr_t)-zip->isize; zip->ibuffer=(uintptr_t)TCOD_list_get(zip->buffer,zip->offset-1); } } libtcod-1.6.4+dfsg/terminal.png000066400000000000000000000065451321276576200164270ustar00rootroot00000000000000PNG  IHDRL\sRGBbKGD pHYs  tIME $#)x IDATx]ˎCЀ ̒  q|Xrجʌr%X*+3Xp\.eYr\.{?5'[DŏroQL=J㿵˴WFO>VQ~NKXeK`u%gap IWFSfU8¼G2o;AYLz7'{#O}#f!(E %^̐9*.af_hߔc;0+CpR-=$,0>~7B2LJ"&AhF/QexK]Tl?)Kk܋/P5SsFT$k6kP}w[ubA!E T2FA1;@`1?4M 4=߉\LZ(`ݢbFzDqv_9:|(XU\h(.q35&\!VLA N`G-BJ#Ǐ d,x$"LAAV[s5/FU3y[[0,K,EDX&a#h|?= O̺ץDXz@U= ? h  -29ޮR2B #>W{ÌHY|l.t=-hSS6~\\炈i; rI)3[qj a=gsԔ. #7WrzNyH#OE\t=PrRԚu(QeШpd=`]x~oEAP?L◳bո*r"֨qrgIF1VUL$r >D:,Յf&v' nmQA(Oh$J5 b\b @qZ)Jeh6">$&d7TA R TRG|`u҆g8}Zh * hUNV/NfC[b[~NU2!4| yU=eR80c _"VG52wRйi0R5L~`T%]VqF4Zn C y͈=4AYfRxNg+?DRHd$˨oŹVXR#Fb+^$4TBG%$:?Q) 0bDU!)DSTXY!`ì}vav>d9)!|g<ҫRd8\SE|E5 iUQP_]n*~,$ث}Jh2LyzU靳]-RS9Y1La*HT)J8ܱn9wAbzbNlABxfjܩה¹S3brgWƓ-6N) Q՞P6Vꏇ_ym_d_崬Q4 86\S׆'ʬwIkHgfwv9/qd&\[*\*ZfdI|f=G{~_g;]֞(=`j)Lfpy_L_wvS;r^)WsZ5‚W.~7ǿ Xt\}^ox QjDiI}(;}fO|^;{}\kNKph0*5.,v~b?؋;Ζ/E4_\qQ j7v_>O-cIENDB`